From 330b803915a395330e5acdf78b4c82f4c4a64d0e Mon Sep 17 00:00:00 2001 From: str4d Date: Thu, 30 Nov 2023 08:04:57 +0000 Subject: [PATCH] deploy: 003619bad4b7d8ae2f128a86a9ae9da7b9947fc1 --- 404.html | 128 +- IDENTIFIERS.json | 19 + ayu-highlight.css | 1 - book.js | 119 +- concepts.html | 133 +- concepts/preliminaries.html | 133 +- css/chrome.css | 192 +- css/general.css | 106 +- css/print.css | 8 +- css/variables.css | 46 +- design.html | 145 +- design/actions.html | 135 +- design/circuit.html | 133 +- design/circuit/commit-ivk.html | 295 +- design/circuit/gadgets.html | 133 +- design/circuit/note-commit.html | 541 ++-- design/commitment-tree.html | 159 +- design/commitments.html | 163 +- design/keys.html | 151 +- design/nullifiers.html | 312 ++- design/signatures.html | 133 +- dev/bench/data.js | 4508 ------------------------------- dev/bench/index.html | 279 -- highlight.css | 39 +- index.html | 137 +- print.html | 1054 ++++---- searcher.js | 3 +- searchindex.js | 2 +- searchindex.json | 2 +- tomorrow-night.css | 6 +- user.html | 133 +- user/creating-notes.html | 133 +- user/integration.html | 133 +- user/keys.html | 133 +- user/spending-notes.html | 133 +- 35 files changed, 2571 insertions(+), 7309 deletions(-) create mode 100644 IDENTIFIERS.json delete mode 100644 dev/bench/data.js delete mode 100644 dev/bench/index.html diff --git a/404.html b/404.html index 2c02f13e..4d5f7b20 100644 --- a/404.html +++ b/404.html @@ -1,42 +1,28 @@ - + - - - + Page not found - The Orchard Book - - - - - + - - - - - - - - @@ -44,19 +30,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/IDENTIFIERS.json b/IDENTIFIERS.json new file mode 100644 index 00000000..8080c0ec --- /dev/null +++ b/IDENTIFIERS.json @@ -0,0 +1,19 @@ +{ + "commit-ivk-bit-lengths": "design/circuit/commit-ivk.html#bit-length-constraints", + "commit-ivk-canonicity-ak": "design/circuit/commit-ivk.html#canonicity-ak", + "commit-ivk-canonicity-nk": "design/circuit/commit-ivk.html#canonicity-nk", + "commit-ivk-decompositions": "design/circuit/commit-ivk.html#constrain-bit-lengths", + "commit-ivk-region-layout": "design/circuit/commit-ivk.html#region-layout", + "note-commit-canonicity-g_d": "design/circuit/note-commit.html#canonicity-g_d", + "note-commit-canonicity-pk_d": "design/circuit/note-commit.html#canonicity-pk_d", + "note-commit-canonicity-psi": "design/circuit/note-commit.html#canonicity-psi", + "note-commit-canonicity-rho": "design/circuit/note-commit.html#canonicity-rho", + "note-commit-canonicity-v": "design/circuit/note-commit.html#canonicity-v", + "note-commit-canonicity-y": "design/circuit/note-commit.html#canonicity-y", + "note-commit-decomposition-b": "design/circuit/note-commit.html#decomposition-b", + "note-commit-decomposition-d": "design/circuit/note-commit.html#decomposition-d", + "note-commit-decomposition-e": "design/circuit/note-commit.html#decomposition-e", + "note-commit-decomposition-g": "design/circuit/note-commit.html#decomposition-g", + "note-commit-decomposition-h": "design/circuit/note-commit.html#decomposition-h", + "note-commit-decomposition-y": "design/circuit/note-commit.html#decomposition-y" +} \ No newline at end of file diff --git a/ayu-highlight.css b/ayu-highlight.css index 0c45c6f1..32c94322 100644 --- a/ayu-highlight.css +++ b/ayu-highlight.css @@ -8,7 +8,6 @@ Original by Dempfi (https://github.com/dempfi/ayu) overflow-x: auto; background: #191f26; color: #e6e1cf; - padding: 0.5em; } .hljs-comment, diff --git a/book.js b/book.js index 5e386369..aa12e7ec 100644 --- a/book.js +++ b/book.js @@ -4,14 +4,16 @@ window.onunload = function () { }; // Global variable, shared between modules -function playground_text(playground) { +function playground_text(playground, hidden = true) { let code_block = playground.querySelector("code"); if (window.ace && code_block.classList.contains("editable")) { let editor = window.ace.edit(code_block); return editor.getValue(); - } else { + } else if (hidden) { return code_block.textContent; + } else { + return code_block.innerText; } } @@ -66,7 +68,7 @@ function playground_text(playground) { } // updates the visibility of play button based on `no_run` class and - // used crates vs ones available on http://play.rust-lang.org + // used crates vs ones available on https://play.rust-lang.org function update_play_button(pre_block, playground_crates) { var play_button = pre_block.querySelector(".play-button"); @@ -108,9 +110,12 @@ function playground_text(playground) { let text = playground_text(code_block); let classes = code_block.querySelector('code').classList; - let has_2018 = classes.contains("edition2018"); - let edition = has_2018 ? "2018" : "2015"; - + let edition = "2015"; + if(classes.contains("edition2018")) { + edition = "2018"; + } else if(classes.contains("edition2021")) { + edition = "2021"; + } var params = { version: "stable", optimize: "0", @@ -133,7 +138,15 @@ function playground_text(playground) { body: JSON.stringify(params) }) .then(response => response.json()) - .then(response => result_block.innerText = response.result) + .then(response => { + if (response.result.trim() === '') { + result_block.innerText = "No output"; + result_block.classList.add("result-no-output"); + } else { + result_block.innerText = response.result; + result_block.classList.remove("result-no-output"); + } + }) .catch(error => result_block.innerText = "Playground Communication: " + error.message); } @@ -151,12 +164,12 @@ function playground_text(playground) { if (window.ace) { // language-rust class needs to be removed for editable // blocks or highlightjs will capture events - Array - .from(document.querySelectorAll('code.editable')) + code_nodes + .filter(function (node) {return node.classList.contains("editable"); }) .forEach(function (block) { block.classList.remove('language-rust'); }); - Array - .from(document.querySelectorAll('code:not(.editable)')) + code_nodes + .filter(function (node) {return !node.classList.contains("editable"); }) .forEach(function (block) { hljs.highlightBlock(block); }); } else { code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); @@ -166,7 +179,7 @@ function playground_text(playground) { // even if highlighting doesn't apply code_nodes.forEach(function (block) { block.classList.add('hljs'); }); - Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) { + Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) { var lines = Array.from(block.querySelectorAll('.boring')); // If no lines were hidden, return @@ -288,6 +301,13 @@ function playground_text(playground) { themePopup.querySelector("button#" + get_theme()).focus(); } + function updateThemeSelected() { + themePopup.querySelectorAll('.theme-selected').forEach(function (el) { + el.classList.remove('theme-selected'); + }); + themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected'); + } + function hideThemes() { themePopup.style.display = 'none'; themeToggleButton.setAttribute('aria-expanded', false); @@ -326,7 +346,7 @@ function playground_text(playground) { } setTimeout(function () { - themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor; + themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor; }, 1); if (window.ace && window.editors) { @@ -343,6 +363,7 @@ function playground_text(playground) { html.classList.remove(previousTheme); html.classList.add(theme); + updateThemeSelected(); } // Set theme @@ -359,7 +380,14 @@ function playground_text(playground) { }); themePopup.addEventListener('click', function (e) { - var theme = e.target.id || e.target.parentElement.id; + var theme; + if (e.target.className === "theme") { + theme = e.target.id; + } else if (e.target.parentElement.className === "theme") { + theme = e.target.parentElement.id; + } else { + return; + } set_theme(theme); }); @@ -413,7 +441,7 @@ function playground_text(playground) { })(); (function sidebar() { - var html = document.querySelector("html"); + var body = document.querySelector("body"); var sidebar = document.getElementById("sidebar"); var sidebarLinks = document.querySelectorAll('#sidebar a'); var sidebarToggleButton = document.getElementById("sidebar-toggle"); @@ -421,8 +449,8 @@ function playground_text(playground) { var firstContact = null; function showSidebar() { - html.classList.remove('sidebar-hidden') - html.classList.add('sidebar-visible'); + body.classList.remove('sidebar-hidden') + body.classList.add('sidebar-visible'); Array.from(sidebarLinks).forEach(function (link) { link.setAttribute('tabIndex', 0); }); @@ -443,8 +471,8 @@ function playground_text(playground) { }); function hideSidebar() { - html.classList.remove('sidebar-visible') - html.classList.add('sidebar-hidden'); + body.classList.remove('sidebar-visible') + body.classList.add('sidebar-hidden'); Array.from(sidebarLinks).forEach(function (link) { link.setAttribute('tabIndex', -1); }); @@ -455,14 +483,14 @@ function playground_text(playground) { // Toggle sidebar sidebarToggleButton.addEventListener('click', function sidebarToggle() { - if (html.classList.contains("sidebar-hidden")) { + if (body.classList.contains("sidebar-hidden")) { var current_width = parseInt( document.documentElement.style.getPropertyValue('--sidebar-width'), 10); if (current_width < 150) { document.documentElement.style.setProperty('--sidebar-width', '150px'); } showSidebar(); - } else if (html.classList.contains("sidebar-visible")) { + } else if (body.classList.contains("sidebar-visible")) { hideSidebar(); } else { if (getComputedStyle(sidebar)['transform'] === 'none') { @@ -478,14 +506,14 @@ function playground_text(playground) { function initResize(e) { window.addEventListener('mousemove', resize, false); window.addEventListener('mouseup', stopResize, false); - html.classList.add('sidebar-resizing'); + body.classList.add('sidebar-resizing'); } function resize(e) { var pos = (e.clientX - sidebar.offsetLeft); if (pos < 20) { hideSidebar(); } else { - if (html.classList.contains("sidebar-hidden")) { + if (body.classList.contains("sidebar-hidden")) { showSidebar(); } pos = Math.min(pos, window.innerWidth - 100); @@ -494,7 +522,7 @@ function playground_text(playground) { } //on mouseup remove windows functions mousemove & mouseup function stopResize(e) { - html.classList.remove('sidebar-resizing'); + body.classList.remove('sidebar-resizing'); window.removeEventListener('mousemove', resize, false); window.removeEventListener('mouseup', stopResize, false); } @@ -523,33 +551,41 @@ function playground_text(playground) { firstContact = null; } }, { passive: true }); - - // Scroll sidebar to current active section - var activeSection = document.getElementById("sidebar").querySelector(".active"); - if (activeSection) { - // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView - activeSection.scrollIntoView({ block: 'center' }); - } })(); (function chapterNavigation() { document.addEventListener('keydown', function (e) { if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } if (window.search && window.search.hasFocus()) { return; } + var html = document.querySelector('html'); + function next() { + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + } + function prev() { + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + } switch (e.key) { case 'ArrowRight': e.preventDefault(); - var nextButton = document.querySelector('.nav-chapters.next'); - if (nextButton) { - window.location.href = nextButton.href; + if (html.dir == 'rtl') { + prev(); + } else { + next(); } break; case 'ArrowLeft': e.preventDefault(); - var previousButton = document.querySelector('.nav-chapters.previous'); - if (previousButton) { - window.location.href = previousButton.href; + if (html.dir == 'rtl') { + next(); + } else { + prev(); } break; } @@ -573,7 +609,7 @@ function playground_text(playground) { text: function (trigger) { hideTooltip(trigger); let playground = trigger.closest("pre"); - return playground_text(playground); + return playground_text(playground, false); } }); @@ -648,13 +684,14 @@ function playground_text(playground) { }, { passive: true }); })(); (function controllBorder() { - menu.classList.remove('bordered'); - document.addEventListener('scroll', function () { + function updateBorder() { if (menu.offsetTop === 0) { menu.classList.remove('bordered'); } else { menu.classList.add('bordered'); } - }, { passive: true }); + } + updateBorder(); + document.addEventListener('scroll', updateBorder, { passive: true }); })(); })(); diff --git a/concepts.html b/concepts.html index 3339b805..5c46dbb6 100644 --- a/concepts.html +++ b/concepts.html @@ -1,40 +1,27 @@ - + Concepts - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/concepts/preliminaries.html b/concepts/preliminaries.html index 323868af..563eedba 100644 --- a/concepts/preliminaries.html +++ b/concepts/preliminaries.html @@ -1,40 +1,27 @@ - + Preliminaries - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/css/chrome.css b/css/chrome.css index 9ca8633a..2314f7a1 100644 --- a/css/chrome.css +++ b/css/chrome.css @@ -2,12 +2,6 @@ @import 'variables.css'; -::-webkit-scrollbar { - background: var(--bg); -} -::-webkit-scrollbar-thumb { - background: var(--scrollbar); -} html { scrollbar-color: var(--scrollbar) var(--bg); } @@ -18,6 +12,19 @@ a > .hljs { color: var(--links); } +/* + body-container is necessary because mobile browsers don't seem to like + overflow-x on the body tag when there is a tag. +*/ +#body-container { + /* + This is used when the sidebar pushes the body content off the side of + the screen on small screens. Without it, dragging on mobile Safari + will want to reposition the viewport in a weird way. + */ + overflow-x: clip; +} + /* Menu Bar */ #menu-bar, @@ -30,9 +37,9 @@ a > .hljs { display: flex; flex-wrap: wrap; background-color: var(--bg); - border-bottom-color: var(--bg); - border-bottom-width: 1px; - border-bottom-style: solid; + border-block-end-color: var(--bg); + border-block-end-width: 1px; + border-block-end-style: solid; } #menu-bar.sticky, .js #menu-bar-hover-placeholder:hover + #menu-bar, @@ -49,7 +56,7 @@ a > .hljs { height: var(--menu-bar-height); } #menu-bar.bordered { - border-bottom-color: var(--table-border-color); + border-block-end-color: var(--table-border-color); } #menu-bar i, #menu-bar .icon-button { position: relative; @@ -86,14 +93,14 @@ a > .hljs { display: flex; margin: 0 5px; } -.no-js .left-buttons { +.no-js .left-buttons button { display: none; } .menu-title { display: inline-block; font-weight: 200; - font-size: 2rem; + font-size: 2.4rem; line-height: var(--menu-bar-height); text-align: center; margin: 0; @@ -153,7 +160,7 @@ a > .hljs { } .nav-wrapper { - margin-top: 50px; + margin-block-start: 50px; display: none; } @@ -166,23 +173,34 @@ a > .hljs { background-color: var(--sidebar-bg); } -.previous { - float: left; -} +/* Only Firefox supports flow-relative values */ +.previous { float: left; } +[dir=rtl] .previous { float: right; } +/* Only Firefox supports flow-relative values */ .next { float: right; right: var(--page-padding); } +[dir=rtl] .next { + float: left; + right: unset; + left: var(--page-padding); +} + +/* Use the correct buttons for RTL layouts*/ +[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";} +[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; } @media only screen and (max-width: 1080px) { .nav-wide-wrapper { display: none; } .nav-wrapper { display: block; } } +/* sidebar-visible */ @media only screen and (max-width: 1380px) { - .sidebar-visible .nav-wide-wrapper { display: none; } - .sidebar-visible .nav-wrapper { display: block; } + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; } + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; } } /* Inline code */ @@ -208,26 +226,65 @@ pre { pre > .buttons { position: absolute; z-index: 100; - right: 5px; - top: 5px; + right: 0px; + top: 2px; + margin: 0px; + padding: 2px 0px; color: var(--sidebar-fg); cursor: pointer; + visibility: hidden; + opacity: 0; + transition: visibility 0.1s linear, opacity 0.1s linear; +} +pre:hover > .buttons { + visibility: visible; + opacity: 1 } pre > .buttons :hover { color: var(--sidebar-active); + border-color: var(--icons-hover); + background-color: var(--theme-hover); } pre > .buttons i { - margin-left: 8px; + margin-inline-start: 8px; } pre > .buttons button { - color: inherit; - background: transparent; - border: none; cursor: inherit; + margin: 0px 5px; + padding: 3px 5px; + font-size: 14px; + + border-style: solid; + border-width: 1px; + border-radius: 4px; + border-color: var(--icons); + background-color: var(--theme-popup-bg); + transition: 100ms; + transition-property: color,border-color,background-color; + color: var(--icons); } +@media (pointer: coarse) { + pre > .buttons button { + /* On mobile, make it easier to tap buttons. */ + padding: 0.3rem 1rem; + } +} +pre > code { + padding: 1rem; +} + +/* FIXME: ACE editors overlap their buttons because ACE does absolute + positioning within the code block which breaks padding. The only solution I + can think of is to move the padding to the outer pre tag (or insert a div + wrapper), but that would require fixing a whole bunch of CSS rules. +*/ +.hljs.ace_editor { + padding: 0rem 0rem; +} + pre > .result { - margin-top: 10px; + margin-block-start: 10px; } /* Search */ @@ -238,8 +295,14 @@ pre > .result { mark { border-radius: 2px; - padding: 0 3px 1px 3px; - margin: 0 -3px -1px -3px; + padding-block-start: 0; + padding-block-end: 1px; + padding-inline-start: 3px; + padding-inline-end: 3px; + margin-block-start: 0; + margin-block-end: -1px; + margin-inline-start: -3px; + margin-inline-end: -3px; background-color: var(--search-mark-bg); transition: background-color 300ms linear; cursor: pointer; @@ -251,14 +314,17 @@ mark.fade-out { } .searchbar-outer { - margin-left: auto; - margin-right: auto; + margin-inline-start: auto; + margin-inline-end: auto; max-width: var(--content-max-width); } #searchbar { width: 100%; - margin: 5px auto 0px auto; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: auto; + margin-inline-end: auto; padding: 10px 16px; transition: box-shadow 300ms ease-in-out; border: 1px solid var(--searchbar-border-color); @@ -274,20 +340,23 @@ mark.fade-out { .searchresults-header { font-weight: bold; font-size: 1em; - padding: 18px 0 0 5px; + padding-block-start: 18px; + padding-block-end: 0; + padding-inline-start: 5px; + padding-inline-end: 0; color: var(--searchresults-header-fg); } .searchresults-outer { - margin-left: auto; - margin-right: auto; + margin-inline-start: auto; + margin-inline-end: auto; max-width: var(--content-max-width); - border-bottom: 1px dashed var(--searchresults-border-color); + border-block-end: 1px dashed var(--searchresults-border-color); } ul#searchresults { list-style: none; - padding-left: 20px; + padding-inline-start: 20px; } ul#searchresults li { margin: 10px 0px; @@ -300,7 +369,10 @@ ul#searchresults li.focus { ul#searchresults span.teaser { display: block; clear: both; - margin: 5px 0 0 20px; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: 20px; + margin-inline-end: 0; font-size: 0.8em; } ul#searchresults span.teaser em { @@ -323,12 +395,14 @@ ul#searchresults span.teaser em { background-color: var(--sidebar-bg); color: var(--sidebar-fg); } +[dir=rtl] .sidebar { left: unset; right: 0; } .sidebar-resizing { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; } +.no-js .sidebar, .js:not(.sidebar-resizing) .sidebar { transition: transform 0.3s; /* Animation: slide away */ } @@ -352,12 +426,18 @@ ul#searchresults span.teaser em { top: 0; bottom: 0; } +[dir=rtl] .sidebar .sidebar-resize-handle { right: unset; left: 0; } .js .sidebar .sidebar-resize-handle { cursor: col-resize; width: 5px; } -.sidebar-hidden .sidebar { +/* sidebar-hidden */ +#sidebar-toggle-anchor:not(:checked) ~ .sidebar { transform: translateX(calc(0px - var(--sidebar-width))); + z-index: -1; +} +[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar { + transform: translateX(var(--sidebar-width)); } .sidebar::-webkit-scrollbar { background: var(--sidebar-bg); @@ -366,19 +446,26 @@ ul#searchresults span.teaser em { background: var(--scrollbar); } -.sidebar-visible .page-wrapper { +/* sidebar-visible */ +#sidebar-toggle-anchor:checked ~ .page-wrapper { transform: translateX(var(--sidebar-width)); } +[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: translateX(calc(0px - var(--sidebar-width))); +} @media only screen and (min-width: 620px) { - .sidebar-visible .page-wrapper { + #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: none; + margin-inline-start: var(--sidebar-width); + } + [dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { transform: none; - margin-left: var(--sidebar-width); } } .chapter { list-style: none outside none; - padding-left: 0; + padding-inline-start: 0; line-height: 2.2em; } @@ -408,7 +495,7 @@ ul#searchresults span.teaser em { .chapter li > a.toggle { cursor: pointer; display: block; - margin-left: auto; + margin-inline-start: auto; padding: 0 10px; user-select: none; opacity: 0.68; @@ -425,7 +512,7 @@ ul#searchresults span.teaser em { .chapter li.chapter-item { line-height: 1.5em; - margin-top: 0.6em; + margin-block-start: 0.6em; } .chapter li.expanded > a.toggle div { @@ -448,7 +535,7 @@ ul#searchresults span.teaser em { .section { list-style: none outside none; - padding-left: 20px; + padding-inline-start: 20px; line-height: 1.9em; } @@ -468,7 +555,10 @@ ul#searchresults span.teaser em { padding: 0; list-style: none; display: none; + /* Don't let the children's background extend past the rounded corners. */ + overflow: hidden; } +[dir=rtl] .theme-popup { left: unset; right: 10px; } .theme-popup .default { color: var(--icons); } @@ -476,10 +566,10 @@ ul#searchresults span.teaser em { width: 100%; border: 0; margin: 0; - padding: 2px 10px; + padding: 2px 20px; line-height: 25px; white-space: nowrap; - text-align: left; + text-align: start; cursor: pointer; color: inherit; background: inherit; @@ -488,8 +578,10 @@ ul#searchresults span.teaser em { .theme-popup .theme:hover { background-color: var(--theme-hover); } -.theme-popup .theme:hover:first-child, -.theme-popup .theme:hover:last-child { - border-top-left-radius: inherit; - border-top-right-radius: inherit; + +.theme-selected::before { + display: inline-block; + content: "✓"; + margin-inline-start: -14px; + width: 14px; } diff --git a/css/general.css b/css/general.css index 815dae1a..e7d20da7 100644 --- a/css/general.css +++ b/css/general.css @@ -5,6 +5,7 @@ :root { /* Browser default font-size is 16px, this way 1 rem = 10px */ font-size: 62.5%; + color-scheme: var(--color-scheme); } html { @@ -12,6 +13,7 @@ html { color: var(--fg); background-color: var(--bg); text-size-adjust: none; + -webkit-text-size-adjust: none; } body { @@ -21,8 +23,19 @@ body { } code { - font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important; - font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */ + font-family: var(--mono-font) !important; + font-size: var(--code-font-size); + direction: ltr !important; +} + +/* make long words/inline code not x overflow */ +main { + overflow-wrap: break-word; +} + +/* make wide tables scroll if they overflow */ +.table-wrapper { + overflow-x: auto; } /* Don't change font size in headers. */ @@ -36,52 +49,60 @@ h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { .hide-boring .boring { display: none; } .hidden { display: none !important; } -h2, h3 { margin-top: 2.5em; } -h4, h5 { margin-top: 2em; } +h2, h3 { margin-block-start: 2.5em; } +h4, h5 { margin-block-start: 2em; } .header + .header h3, .header + .header h4, .header + .header h5 { - margin-top: 1em; + margin-block-start: 1em; } -h1 a.header:target::before, -h2 a.header:target::before, -h3 a.header:target::before, -h4 a.header:target::before { +h1:target::before, +h2:target::before, +h3:target::before, +h4:target::before, +h5:target::before, +h6:target::before { display: inline-block; content: "»"; - margin-left: -30px; + margin-inline-start: -30px; width: 30px; } -h1 a.header:target, -h2 a.header:target, -h3 a.header:target, -h4 a.header:target { +/* This is broken on Safari as of version 14, but is fixed + in Safari Technology Preview 117 which I think will be Safari 14.2. + https://bugs.webkit.org/show_bug.cgi?id=218076 +*/ +:target { + /* Safari does not support logical properties */ scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); } .page { outline: 0; padding: 0 var(--page-padding); - margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ + margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ } .page-wrapper { box-sizing: border-box; + background-color: var(--bg); } +.no-js .page-wrapper, .js:not(.sidebar-resizing) .page-wrapper { transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ } +[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { + transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +} .content { overflow-y: auto; - padding: 0 15px; - padding-bottom: 50px; + padding: 0 5px 50px 5px; } .content main { - margin-left: auto; - margin-right: auto; + margin-inline-start: auto; + margin-inline-end: auto; max-width: var(--content-max-width); } .content p { line-height: 1.45em; } @@ -89,7 +110,7 @@ h4 a.header:target { .content ul { line-height: 1.45em; } .content a { text-decoration: none; } .content a:hover { text-decoration: underline; } -.content img { max-width: 100%; } +.content img, .content video { max-width: 100%; } .content .header:link, .content .header:visited { color: var(--fg); @@ -131,14 +152,49 @@ blockquote { padding: 0 20px; color: var(--fg); background-color: var(--quote-bg); - border-top: .1em solid var(--quote-border); - border-bottom: .1em solid var(--quote-border); + border-block-start: .1em solid var(--quote-border); + border-block-end: .1em solid var(--quote-border); } +.warning { + margin: 20px; + padding: 0 20px; + border-inline-start: 2px solid var(--warning-border); +} + +.warning:before { + position: absolute; + width: 3rem; + height: 3rem; + margin-inline-start: calc(-1.5rem - 21px); + content: "ⓘ"; + text-align: center; + background-color: var(--bg); + color: var(--warning-border); + font-weight: bold; + font-size: 2rem; +} + +blockquote .warning:before { + background-color: var(--quote-bg); +} + +kbd { + background-color: var(--table-border-color); + border-radius: 4px; + border: solid 1px var(--theme-popup-border); + box-shadow: inset 0 -1px 0 var(--theme-hover); + display: inline-block; + font-size: var(--code-font-size); + font-family: var(--mono-font); + line-height: 10px; + padding: 4px 5px; + vertical-align: middle; +} :not(.footnote-definition) + .footnote-definition, .footnote-definition + :not(.footnote-definition) { - margin-top: 2em; + margin-block-start: 2em; } .footnote-definition { font-size: 0.9em; @@ -172,3 +228,7 @@ blockquote { margin: 5px 0px; font-weight: bold; } + +.result-no-output { + font-style: italic; +} diff --git a/css/print.css b/css/print.css index 5e690f75..dcf0ba64 100644 --- a/css/print.css +++ b/css/print.css @@ -8,7 +8,7 @@ #page-wrapper.page-wrapper { transform: none; - margin-left: 0px; + margin-inline-start: 0px; overflow-y: initial; } @@ -23,11 +23,7 @@ } code { - background-color: #666666; - border-radius: 5px; - - /* Force background to be printed in Chrome */ - -webkit-print-color-adjust: exact; + direction: ltr !important; } pre > .buttons { diff --git a/css/variables.css b/css/variables.css index 9534ec8d..10a75909 100644 --- a/css/variables.css +++ b/css/variables.css @@ -6,6 +6,8 @@ --page-padding: 15px; --content-max-width: 750px; --menu-bar-height: 50px; + --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; + --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ } /* Themes */ @@ -36,6 +38,8 @@ --quote-bg: hsl(226, 15%, 17%); --quote-border: hsl(226, 15%, 22%); + --warning-border: #ff8e00; + --table-border-color: hsl(210, 25%, 13%); --table-header-bg: hsl(210, 25%, 28%); --table-alternate-bg: hsl(210, 25%, 11%); @@ -48,6 +52,8 @@ --searchresults-border-color: #888; --searchresults-li-bg: #252932; --search-mark-bg: #e3b171; + + --color-scheme: dark; } .coal { @@ -67,7 +73,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #c5c8c6; --theme-popup-bg: #141617; --theme-popup-border: #43484d; @@ -76,6 +82,8 @@ --quote-bg: hsl(234, 21%, 18%); --quote-border: hsl(234, 21%, 23%); + --warning-border: #ff8e00; + --table-border-color: hsl(200, 7%, 13%); --table-header-bg: hsl(200, 7%, 28%); --table-alternate-bg: hsl(200, 7%, 11%); @@ -88,26 +96,28 @@ --searchresults-border-color: #98a3ad; --searchresults-li-bg: #2b2b2f; --search-mark-bg: #355c7d; + + --color-scheme: dark; } .light { --bg: hsl(0, 0%, 100%); - --fg: #333333; + --fg: hsl(0, 0%, 0%); --sidebar-bg: #fafafa; - --sidebar-fg: #364149; + --sidebar-fg: hsl(0, 0%, 0%); --sidebar-non-existant: #aaaaaa; - --sidebar-active: #008cff; + --sidebar-active: #1f1fff; --sidebar-spacer: #f4f4f4; - --scrollbar: #cccccc; + --scrollbar: #8F8F8F; - --icons: #cccccc; - --icons-hover: #333333; + --icons: #747474; + --icons-hover: #000000; - --links: #4183c4; + --links: #20609f; - --inline-code-color: #6e6b5e; + --inline-code-color: #301900; --theme-popup-bg: #fafafa; --theme-popup-border: #cccccc; @@ -116,6 +126,8 @@ --quote-bg: hsl(197, 37%, 96%); --quote-border: hsl(197, 37%, 91%); + --warning-border: #ff8e00; + --table-border-color: hsl(0, 0%, 95%); --table-header-bg: hsl(0, 0%, 80%); --table-alternate-bg: hsl(0, 0%, 97%); @@ -128,6 +140,8 @@ --searchresults-border-color: #888; --searchresults-li-bg: #e4f2fe; --search-mark-bg: #a2cff5; + + --color-scheme: light; } .navy { @@ -147,7 +161,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #c5c8c6; --theme-popup-bg: #161923; --theme-popup-border: #737480; @@ -156,6 +170,8 @@ --quote-bg: hsl(226, 15%, 17%); --quote-border: hsl(226, 15%, 22%); + --warning-border: #ff8e00; + --table-border-color: hsl(226, 23%, 16%); --table-header-bg: hsl(226, 23%, 31%); --table-alternate-bg: hsl(226, 23%, 14%); @@ -168,6 +184,8 @@ --searchresults-border-color: #5c5c68; --searchresults-li-bg: #242430; --search-mark-bg: #a2cff5; + + --color-scheme: dark; } .rust { @@ -196,6 +214,8 @@ --quote-bg: hsl(60, 5%, 75%); --quote-border: hsl(60, 5%, 70%); + --warning-border: #ff8e00; + --table-border-color: hsl(60, 9%, 82%); --table-header-bg: #b3a497; --table-alternate-bg: hsl(60, 9%, 84%); @@ -208,6 +228,8 @@ --searchresults-border-color: #888; --searchresults-li-bg: #dec2a2; --search-mark-bg: #e69f67; + + --color-scheme: light; } @media (prefers-color-scheme: dark) { @@ -228,7 +250,7 @@ --links: #2b79a2; - --inline-code-color: #c5c8c6;; + --inline-code-color: #c5c8c6; --theme-popup-bg: #141617; --theme-popup-border: #43484d; @@ -237,6 +259,8 @@ --quote-bg: hsl(234, 21%, 18%); --quote-border: hsl(234, 21%, 23%); + --warning-border: #ff8e00; + --table-border-color: hsl(200, 7%, 13%); --table-header-bg: hsl(200, 7%, 28%); --table-alternate-bg: hsl(200, 7%, 11%); diff --git a/design.html b/design.html index ec107a96..5319b907 100644 --- a/design.html +++ b/design.html @@ -1,40 +1,27 @@ - + Design - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/actions.html b/design/actions.html index 9e277178..3e7689ca 100644 --- a/design/actions.html +++ b/design/actions.html @@ -1,40 +1,27 @@ - + Actions - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/circuit.html b/design/circuit.html index 0c161afd..b001df6d 100644 --- a/design/circuit.html +++ b/design/circuit.html @@ -1,40 +1,27 @@ - + Circuit - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/circuit/commit-ivk.html b/design/circuit/commit-ivk.html index 50fdd7f2..5e9ad323 100644 --- a/design/circuit/commit-ivk.html +++ b/design/circuit/commit-ivk.html @@ -1,40 +1,27 @@ - + CommitIvk - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/circuit/gadgets.html b/design/circuit/gadgets.html index a5df5460..51e412dc 100644 --- a/design/circuit/gadgets.html +++ b/design/circuit/gadgets.html @@ -1,40 +1,27 @@ - + Gadgets - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/circuit/note-commit.html b/design/circuit/note-commit.html index 003edd6c..475d7321 100644 --- a/design/circuit/note-commit.html +++ b/design/circuit/note-commit.html @@ -1,40 +1,27 @@ - + NoteCommit - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/commitment-tree.html b/design/commitment-tree.html index f23baf68..f06615c8 100644 --- a/design/commitment-tree.html +++ b/design/commitment-tree.html @@ -1,40 +1,27 @@ - + Commitment tree - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/commitments.html b/design/commitments.html index bc46a750..4f114ea9 100644 --- a/design/commitments.html +++ b/design/commitments.html @@ -1,40 +1,27 @@ - + Commitments - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/keys.html b/design/keys.html index 9b5b4925..9dbaca7b 100644 --- a/design/keys.html +++ b/design/keys.html @@ -1,40 +1,27 @@ - + Keys and addresses - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/nullifiers.html b/design/nullifiers.html index 735c08e7..f43706f3 100644 --- a/design/nullifiers.html +++ b/design/nullifiers.html @@ -1,40 +1,27 @@ - + Nullifiers - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/design/signatures.html b/design/signatures.html index f5609aa4..dbe490cc 100644 --- a/design/signatures.html +++ b/design/signatures.html @@ -1,40 +1,27 @@ - + Signatures - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/dev/bench/data.js b/dev/bench/data.js deleted file mode 100644 index 2b65fe1a..00000000 --- a/dev/bench/data.js +++ /dev/null @@ -1,4508 +0,0 @@ -window.BENCHMARK_DATA = { - "lastUpdate": 1694198469926, - "repoUrl": "https://github.com/zcash/orchard", - "entries": { - "Orchard Benchmarks": [ - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "de37f1cdbcff53e5ab26a485d058bf8c41bd5626", - "message": "Merge pull request #328 from zcash/release-0.1.0\n\nRelease 0.1.0", - "timestamp": "2022-05-11T00:05:04+01:00", - "tree_id": "324bc3f9556eaaa818ac438fd0b9cc283e17a7c0", - "url": "https://github.com/zcash/orchard/commit/de37f1cdbcff53e5ab26a485d058bf8c41bd5626" - }, - "date": 1652225089357, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4857861122, - "range": "± 71667115", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4806370052, - "range": "± 25223232", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6846933148, - "range": "± 30191351", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8894090130, - "range": "± 32810080", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 41323752, - "range": "± 855174", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 41205365, - "range": "± 509068", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 46165883, - "range": "± 1317441", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 50159316, - "range": "± 8203884", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1317079, - "range": "± 4192", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 165717, - "range": "± 777", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1314046, - "range": "± 791", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 168781331, - "range": "± 51810", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 25912834, - "range": "± 17450", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2923277, - "range": "± 1651", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 25873279, - "range": "± 16732", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2879646, - "range": "± 1851", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 129525905, - "range": "± 339536", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 14554521, - "range": "± 7564", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 128390326, - "range": "± 44923", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 14327243, - "range": "± 9714", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 258982563, - "range": "± 118605", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 29075555, - "range": "± 15369", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 258507780, - "range": "± 448378", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 28635284, - "range": "± 6284", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 617257, - "range": "± 252", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 684808, - "range": "± 432", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "57410303+steven-ecc@users.noreply.github.com", - "name": "Steven", - "username": "steven-ecc" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "4f3f0eaa2d3c5368ada0e0caf68f34f186ac3f31", - "message": "Merge pull request #331 from steven-ecc/update-bosl-exceptions\n\nAdd exception text. Comments noted for future iterations of the exception text.", - "timestamp": "2022-05-19T15:23:13-07:00", - "tree_id": "90facd0d43a82ab175decb4b45d854b27f705e43", - "url": "https://github.com/zcash/orchard/commit/4f3f0eaa2d3c5368ada0e0caf68f34f186ac3f31" - }, - "date": 1653000030188, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4188425174, - "range": "± 37654822", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4171913140, - "range": "± 5855417", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5951132700, - "range": "± 7589743", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7722661839, - "range": "± 13253310", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 37508053, - "range": "± 340883", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 37288717, - "range": "± 269303", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 41780303, - "range": "± 213797", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 45583355, - "range": "± 335779", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1241924, - "range": "± 888", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 157163, - "range": "± 94", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1240635, - "range": "± 685", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 161843079, - "range": "± 317630", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 24401992, - "range": "± 16492", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2752834, - "range": "± 1740", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24366225, - "range": "± 10869", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2707847, - "range": "± 1190", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 121893216, - "range": "± 54126", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13692403, - "range": "± 7607", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 121771857, - "range": "± 45733", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13480243, - "range": "± 7491", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 243885269, - "range": "± 204870", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27378850, - "range": "± 12215", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 243564457, - "range": "± 96469", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 26937889, - "range": "± 21265", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 579322, - "range": "± 441", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 639203, - "range": "± 644", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "36d263fb19cf4b88200617c4bbe7a91b66bf4869", - "message": "Merge pull request #321 from zcash/protocol-rule-links\n\nAdd protocol rule links for the Orchard circuit constraints", - "timestamp": "2022-05-27T17:03:05+01:00", - "tree_id": "fecb70418689fa5f4048eb6b81ddc8953043125d", - "url": "https://github.com/zcash/orchard/commit/36d263fb19cf4b88200617c4bbe7a91b66bf4869" - }, - "date": 1653668550238, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4896161498, - "range": "± 116066658", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4805659975, - "range": "± 46141511", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6993085222, - "range": "± 150065534", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 9011696955, - "range": "± 144668991", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 39795058, - "range": "± 3236745", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 41072414, - "range": "± 2855423", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 44114265, - "range": "± 1900126", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 48523751, - "range": "± 3452846", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1304420, - "range": "± 42601", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 166162, - "range": "± 22043", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1212603, - "range": "± 56153", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 159555070, - "range": "± 5375052", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 26086218, - "range": "± 1052676", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2903194, - "range": "± 113691", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24025506, - "range": "± 860165", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2818166, - "range": "± 139461", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 129326340, - "range": "± 4419376", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 14136524, - "range": "± 681187", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 121534562, - "range": "± 5324261", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 14262416, - "range": "± 1327009", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 258332716, - "range": "± 7834829", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 28180898, - "range": "± 1415950", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 240414860, - "range": "± 6799570", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27273424, - "range": "± 1337633", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 583931, - "range": "± 32798", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 652253, - "range": "± 34360", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "daira@jacaranda.org", - "name": "Daira Hopwood", - "username": "daira" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "8aba4c59fdc02417be6af061116e1debef32dfef", - "message": "Merge pull request #333 from zcash/bosl-copyright\n\nChange copyright attribution for the LICENSE-BOSL file", - "timestamp": "2022-06-17T00:02:50+01:00", - "tree_id": "bd7b1f6ae7486f59a15e79978afeb7922fb3383d", - "url": "https://github.com/zcash/orchard/commit/8aba4c59fdc02417be6af061116e1debef32dfef" - }, - "date": 1655421711741, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4492637451, - "range": "± 101557826", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4652399797, - "range": "± 34800678", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6522233454, - "range": "± 172623464", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8323855015, - "range": "± 58371253", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 39722624, - "range": "± 2321928", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 45235344, - "range": "± 5049562", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 51762583, - "range": "± 7325553", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 57651948, - "range": "± 7122289", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1256746, - "range": "± 13720", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 158874, - "range": "± 304", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1252008, - "range": "± 5908", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 163696621, - "range": "± 671268", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 24712459, - "range": "± 100244", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2802864, - "range": "± 21785", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24639376, - "range": "± 120769", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2798408, - "range": "± 271074", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 123508547, - "range": "± 268119", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13944219, - "range": "± 34962", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 123142874, - "range": "± 312553", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13731367, - "range": "± 29846", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 246856359, - "range": "± 615575", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27878870, - "range": "± 62192", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 246214012, - "range": "± 463694", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27452709, - "range": "± 117641", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 592961, - "range": "± 5665", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 656183, - "range": "± 3507", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "b448f3f4c5d65fd7bc167df3d4f73f4bb94b7806", - "message": "Merge pull request #336 from zcash/halo2_proofs-0.2.0\n\nMigrate to `halo2_proofs 0.2.0`", - "timestamp": "2022-06-23T20:44:47+01:00", - "tree_id": "5a6d27797a05d7243e20939e71f7e3f0e795a25f", - "url": "https://github.com/zcash/orchard/commit/b448f3f4c5d65fd7bc167df3d4f73f4bb94b7806" - }, - "date": 1656014538567, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4158299441, - "range": "± 25948467", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4163640304, - "range": "± 18157834", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5926812337, - "range": "± 6604737", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7665107440, - "range": "± 10399162", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33672707, - "range": "± 374303", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33646280, - "range": "± 207722", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 37669909, - "range": "± 357838", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 42027646, - "range": "± 869449", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1239408, - "range": "± 864", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 157378, - "range": "± 97", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1238776, - "range": "± 4066", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 161066147, - "range": "± 28815", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 24355646, - "range": "± 10519", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2753577, - "range": "± 11630", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24320962, - "range": "± 9375", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2709772, - "range": "± 1257", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 121704241, - "range": "± 22025", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13699652, - "range": "± 71865", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 121525027, - "range": "± 62455", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13479413, - "range": "± 4188", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 243432429, - "range": "± 320674", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27374528, - "range": "± 14064", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 243092217, - "range": "± 525147", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 26946555, - "range": "± 13121", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 579609, - "range": "± 382", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 638550, - "range": "± 392", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "6c0532776c9e8ccb20af8f360c9b60a2e4d10f58", - "message": "Merge pull request #338 from zcash/batch-validation\n\nAdd `orchard::bundle::BatchValidator`", - "timestamp": "2022-06-23T23:10:52+01:00", - "tree_id": "bf3f7748df5c80da4cce5d103c019ce7d732ef2f", - "url": "https://github.com/zcash/orchard/commit/6c0532776c9e8ccb20af8f360c9b60a2e4d10f58" - }, - "date": 1656023240105, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3735736772, - "range": "± 69279925", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3740541533, - "range": "± 18940397", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5331292788, - "range": "± 31781313", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 6853936504, - "range": "± 304428882", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 26401078, - "range": "± 1792517", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 26533979, - "range": "± 1581145", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 32580434, - "range": "± 1875914", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36470013, - "range": "± 1739249", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 924629, - "range": "± 563", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 117146, - "range": "± 357", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 922283, - "range": "± 674", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 118286820, - "range": "± 240428", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 20629022, - "range": "± 8787", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2067100, - "range": "± 4490", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 18150311, - "range": "± 44809", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2035277, - "range": "± 6648", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 90974881, - "range": "± 136860", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 10286903, - "range": "± 21558", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 90703200, - "range": "± 96949", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 10130485, - "range": "± 7129", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 181925125, - "range": "± 696734", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 20561083, - "range": "± 9831", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 181479961, - "range": "± 171053", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 20240018, - "range": "± 73385", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 436079, - "range": "± 730", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 546120, - "range": "± 441", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "1a77930f5ff314b5ae8165c555787eb0c725c76c", - "message": "Merge pull request #341 from zcash/minor-fixes\n\nMinor fixes", - "timestamp": "2022-06-24T00:24:04+01:00", - "tree_id": "ed9d78a708af087b6a7a2c489ed234881d67a8b4", - "url": "https://github.com/zcash/orchard/commit/1a77930f5ff314b5ae8165c555787eb0c725c76c" - }, - "date": 1656027819027, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4620912730, - "range": "± 54208678", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4604719883, - "range": "± 24543374", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6554539537, - "range": "± 22124787", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8508940619, - "range": "± 32859422", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 36007496, - "range": "± 1089896", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 35781436, - "range": "± 398079", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 39569062, - "range": "± 1010581", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 44965815, - "range": "± 1243880", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1257010, - "range": "± 700", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 159188, - "range": "± 184", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1253535, - "range": "± 2064", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 161025305, - "range": "± 44717", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 24738777, - "range": "± 6559", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2811563, - "range": "± 1675", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24679778, - "range": "± 12561", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2768002, - "range": "± 1002", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 123615854, - "range": "± 29584", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13993210, - "range": "± 6912", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 123343009, - "range": "± 50930", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13773835, - "range": "± 4814", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 247174158, - "range": "± 77741", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27972271, - "range": "± 142241", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 246611794, - "range": "± 66386", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27526217, - "range": "± 16184", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 592525, - "range": "± 270", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 655869, - "range": "± 471", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "baabe3d7e227ab329863e09edf8fbcf0584516c1", - "message": "Merge pull request #340 from zingolabs/enable_compact_action_and_orchard_domain_creation_without_action\n\nAdd OrchardDomain::for_nullifier and CompactAction::from_parts", - "timestamp": "2022-06-24T16:32:34+01:00", - "tree_id": "c4012818420e199df5ffec14d71efb1561121ee2", - "url": "https://github.com/zcash/orchard/commit/baabe3d7e227ab329863e09edf8fbcf0584516c1" - }, - "date": 1656085742260, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3746831883, - "range": "± 153670477", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3835463640, - "range": "± 97352434", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5347678165, - "range": "± 12554500", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 6927925504, - "range": "± 15481350", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29153882, - "range": "± 117956", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29876846, - "range": "± 1186928", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 32118338, - "range": "± 387792", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 35461424, - "range": "± 114429", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 930934, - "range": "± 8575", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 117825, - "range": "± 97", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 929484, - "range": "± 1221", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 118550308, - "range": "± 141469", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 18310231, - "range": "± 95963", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2358788, - "range": "± 854", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 18273910, - "range": "± 27965", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2050760, - "range": "± 2318", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 91487176, - "range": "± 62158", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 10367202, - "range": "± 11054", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 91299925, - "range": "± 87663", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 10205420, - "range": "± 11092", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 183000006, - "range": "± 2921400", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 20709947, - "range": "± 14994", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 182569267, - "range": "± 238245", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 20395596, - "range": "± 99812", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 436121, - "range": "± 478", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 546244, - "range": "± 1359", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "3faab98e9e82618a0f2d887054e9e28b0f7947dd", - "message": "Merge pull request #342 from zcash/release-0.2.0\n\nRelease 0.2.0", - "timestamp": "2022-06-24T17:23:22+01:00", - "tree_id": "c1dda5f72c5100a527057bd293cc8c818e944193", - "url": "https://github.com/zcash/orchard/commit/3faab98e9e82618a0f2d887054e9e28b0f7947dd" - }, - "date": 1656088853172, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4169219965, - "range": "± 29134136", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4151420331, - "range": "± 12535449", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5900912055, - "range": "± 18506669", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7653817790, - "range": "± 22395823", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33701091, - "range": "± 635431", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33785007, - "range": "± 119038", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 38437841, - "range": "± 416331", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 42001820, - "range": "± 816693", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1239091, - "range": "± 915", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 158061, - "range": "± 124", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1235273, - "range": "± 712", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 160387636, - "range": "± 181766", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 24357025, - "range": "± 8480", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2766911, - "range": "± 2053", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 24272625, - "range": "± 7364", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2723501, - "range": "± 1148", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 121747614, - "range": "± 45332", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13762512, - "range": "± 37345", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 121284219, - "range": "± 26530", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13543166, - "range": "± 5001", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 243464845, - "range": "± 73151", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27500431, - "range": "± 9873", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 242536015, - "range": "± 62397", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27064583, - "range": "± 14011", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 579982, - "range": "± 1653", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 638128, - "range": "± 1849", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "daira@jacaranda.org", - "name": "Daira Hopwood", - "username": "daira" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "33f1c1141e50adb68715f3359bd75378b4756cca", - "message": "Merge pull request #357 from daira/prepare-epks-and-ivks\n\nDummy implementation of Domain API change for prepared ivk and epk", - "timestamp": "2022-09-15T03:35:10+01:00", - "tree_id": "baba707b8bbdedc5205db31a72a517b84dfe1e42", - "url": "https://github.com/zcash/orchard/commit/33f1c1141e50adb68715f3359bd75378b4756cca" - }, - "date": 1663210388829, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4597524901, - "range": "± 42105257", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4617153789, - "range": "± 56604914", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6571402211, - "range": "± 60506294", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8559436670, - "range": "± 109387726", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 36442979, - "range": "± 1171091", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 35374408, - "range": "± 1218836", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 40529387, - "range": "± 1334391", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 44787487, - "range": "± 2033491", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1214788, - "range": "± 39747", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 157083, - "range": "± 3227", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1233943, - "range": "± 33991", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 155983013, - "range": "± 2689080", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 13401008, - "range": "± 340189", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2797446, - "range": "± 48034", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 13461009, - "range": "± 253710", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2712345, - "range": "± 55665", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 66052428, - "range": "± 1648969", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13716689, - "range": "± 333589", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 68243465, - "range": "± 732283", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13495424, - "range": "± 283188", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 135519922, - "range": "± 2277543", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27493780, - "range": "± 531790", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 135008360, - "range": "± 1951955", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27382679, - "range": "± 321322", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 582644, - "range": "± 11873", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 632666, - "range": "± 25404", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "d3d51a5b78b1e53745b7c55716a06df0a5baf759", - "message": "Merge pull request #358 from zcash/fix-broken-patch\n\nPoint patch directive at `zcash/librustzcash`", - "timestamp": "2022-09-15T17:24:26+01:00", - "tree_id": "71f31b374549836a5555d87ad6d5f195bcc3db98", - "url": "https://github.com/zcash/orchard/commit/d3d51a5b78b1e53745b7c55716a06df0a5baf759" - }, - "date": 1663260056781, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4166633485, - "range": "± 213833617", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4167330085, - "range": "± 17014001", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5933324038, - "range": "± 6793484", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7696692823, - "range": "± 13758984", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33888522, - "range": "± 342018", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33803873, - "range": "± 259662", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 38124548, - "range": "± 279809", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 41963598, - "range": "± 292390", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1239898, - "range": "± 11222", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 156910, - "range": "± 77", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1236016, - "range": "± 1023", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 159741095, - "range": "± 38605", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 13522706, - "range": "± 11102", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2755167, - "range": "± 774", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 13505219, - "range": "± 9623", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2711775, - "range": "± 856", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 67509048, - "range": "± 39158", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13704193, - "range": "± 5746", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 67414299, - "range": "± 153227", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13491568, - "range": "± 5960", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 134992989, - "range": "± 103648", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27395585, - "range": "± 107106", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 134775592, - "range": "± 84593", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 26964013, - "range": "± 10601", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 580059, - "range": "± 289", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 636661, - "range": "± 2438", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "b81d0d1198065cfe73402c302b8d38158c1e3393", - "message": "Merge pull request #344 from zingolabs/publicize_note_and_diversifier_construction\n\nPublicize necessary functionality for creating diversifiers and notes from data", - "timestamp": "2022-09-15T12:39:56-06:00", - "tree_id": "01eb6d03b0c7e863db5f437ce86384bb1aad66b6", - "url": "https://github.com/zcash/orchard/commit/b81d0d1198065cfe73402c302b8d38158c1e3393" - }, - "date": 1663268160723, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3815534936, - "range": "± 61009793", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3804309027, - "range": "± 7559606", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5445408851, - "range": "± 22698230", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7060478413, - "range": "± 17654151", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29588863, - "range": "± 233616", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29731516, - "range": "± 389368", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 33281731, - "range": "± 1057671", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36622429, - "range": "± 239020", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1591100, - "range": "± 20964", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 132027, - "range": "± 57", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1588571, - "range": "± 557", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 132657386, - "range": "± 40430", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16871340, - "range": "± 5005", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2325954, - "range": "± 932", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16874482, - "range": "± 5444", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2290618, - "range": "± 1037", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84283938, - "range": "± 32886", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11570908, - "range": "± 3354", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84320165, - "range": "± 44084", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11395835, - "range": "± 3679", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 168547692, - "range": "± 143782", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 23126312, - "range": "± 213673", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168580026, - "range": "± 45876", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22772524, - "range": "± 7221", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 494371, - "range": "± 284", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 545960, - "range": "± 360", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "4231aa28b2fd451fac7d17ae8b387a848f8133b9", - "message": "Merge pull request #343 from zcash/add-proof-to-batch\n\nExpose `Proof::add_to_batch` in public API", - "timestamp": "2022-09-15T20:18:34+01:00", - "tree_id": "21f980c48ced6e02edf1dda3b742e37e1dbefee5", - "url": "https://github.com/zcash/orchard/commit/4231aa28b2fd451fac7d17ae8b387a848f8133b9" - }, - "date": 1663270480776, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3872025044, - "range": "± 50988939", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3851206810, - "range": "± 14766260", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5500036174, - "range": "± 21131871", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7121561951, - "range": "± 24970742", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29842870, - "range": "± 484587", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29703148, - "range": "± 269958", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 33191455, - "range": "± 190476", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36911634, - "range": "± 1618228", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1593170, - "range": "± 13601", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 132024, - "range": "± 116", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1589514, - "range": "± 10414", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 135197759, - "range": "± 93397", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16888352, - "range": "± 88327", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2330123, - "range": "± 1786", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16854391, - "range": "± 5273", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2294195, - "range": "± 465", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84382538, - "range": "± 299186", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11593791, - "range": "± 3604", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84215159, - "range": "± 26064", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11411995, - "range": "± 3400", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 168726162, - "range": "± 55855", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 23166218, - "range": "± 7906", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168393486, - "range": "± 31584", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22814076, - "range": "± 7439", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 494733, - "range": "± 976", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 546257, - "range": "± 482", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "daira@jacaranda.org", - "name": "Daira Hopwood", - "username": "daira" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "f206b3f5d4e31bba75d03d9d03d5fa25825a9384", - "message": "Merge pull request #352 from zingolabs/add_value_balance_to_builder\n\nadd value_balance to builder", - "timestamp": "2022-09-19T13:20:17+01:00", - "tree_id": "633a040a28796a25cd4fcca53dd5551d6d8201b1", - "url": "https://github.com/zcash/orchard/commit/f206b3f5d4e31bba75d03d9d03d5fa25825a9384" - }, - "date": 1663591188107, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4838776722, - "range": "± 68913761", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4856872739, - "range": "± 53059212", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6989459401, - "range": "± 76470339", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8997503622, - "range": "± 87428530", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 37237925, - "range": "± 2123349", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 37583826, - "range": "± 2125249", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 42090610, - "range": "± 2452509", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 46321385, - "range": "± 3264082", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 2132098, - "range": "± 107086", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 178088, - "range": "± 9863", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1900233, - "range": "± 185160", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 161987067, - "range": "± 8210477", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 22424156, - "range": "± 890109", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 3045509, - "range": "± 96654", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 20454536, - "range": "± 911534", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2778198, - "range": "± 87325", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 111865125, - "range": "± 2265826", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 14237171, - "range": "± 675436", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 101046869, - "range": "± 5381833", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13632506, - "range": "± 974639", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 226412650, - "range": "± 7349793", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 28087601, - "range": "± 1169108", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 200607216, - "range": "± 5249689", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27367658, - "range": "± 1393173", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 603546, - "range": "± 33856", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 654392, - "range": "± 34216", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "75ed8cd806734074a3baeb3279c34f7257e33726", - "message": "Merge pull request #348 from jarys/circuit-constructor\n\nAdd `Circuit::from_action_context` constructor", - "timestamp": "2022-09-26T15:39:09+01:00", - "tree_id": "bed7080fdc72f83d23a45d9ac5b9b1fa0197cf08", - "url": "https://github.com/zcash/orchard/commit/75ed8cd806734074a3baeb3279c34f7257e33726" - }, - "date": 1664204173219, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4155654774, - "range": "± 113986369", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4143057763, - "range": "± 14071265", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5900352982, - "range": "± 13070182", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7653436183, - "range": "± 13592178", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33872632, - "range": "± 713224", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33819702, - "range": "± 197963", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 38114807, - "range": "± 275240", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 41760000, - "range": "± 525362", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1886160, - "range": "± 1120", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 156499, - "range": "± 72", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1883140, - "range": "± 572", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 166529888, - "range": "± 54171", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 19981777, - "range": "± 8034", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2747228, - "range": "± 1093", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 19960988, - "range": "± 14480", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2703763, - "range": "± 23895", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 99759452, - "range": "± 443626", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13668465, - "range": "± 8404", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 99669874, - "range": "± 28354", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13450301, - "range": "± 99196", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 199519517, - "range": "± 315629", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27313906, - "range": "± 10565", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 199312961, - "range": "± 524278", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 26888411, - "range": "± 12651", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 579225, - "range": "± 2279", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 637313, - "range": "± 443", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "33bce9b56726676addb8c180b2a4297493e2d2eb", - "message": "Merge pull request #359 from daira/add-value-balance-to-builder-docfix\n\nCorrect the doc comment and add a test for `Builder::value_balance`", - "timestamp": "2022-10-10T13:36:35-06:00", - "tree_id": "c2f8d0924cc768246003f091d965cbfd49964b07", - "url": "https://github.com/zcash/orchard/commit/33bce9b56726676addb8c180b2a4297493e2d2eb" - }, - "date": 1665431601685, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3845416363, - "range": "± 40009820", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3826001252, - "range": "± 17084114", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5462812505, - "range": "± 14829539", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7071302148, - "range": "± 24445515", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29897568, - "range": "± 910863", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29641672, - "range": "± 338201", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 33589917, - "range": "± 975782", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36797036, - "range": "± 788586", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1585784, - "range": "± 702", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 132081, - "range": "± 74", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1592105, - "range": "± 909", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 132735250, - "range": "± 325715", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16913142, - "range": "± 8242", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2307196, - "range": "± 523", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16887623, - "range": "± 5491", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2291176, - "range": "± 1310", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84536593, - "range": "± 44816", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11575196, - "range": "± 5119", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84375929, - "range": "± 38225", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11396279, - "range": "± 4219", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 169041687, - "range": "± 406416", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 23132975, - "range": "± 55509", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168713787, - "range": "± 51188", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22791639, - "range": "± 13358", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 494539, - "range": "± 2467", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 545723, - "range": "± 273", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "73784af51859496eb16c0e24b88dae0682d4ef69", - "message": "Merge pull request #361 from zcash/zcash_note_encryption-0.2\n\nzcash_note_encryption 0.2", - "timestamp": "2022-10-13T23:04:53+01:00", - "tree_id": "918f75e2f2703ff7627112381a868b5b2a5900ae", - "url": "https://github.com/zcash/orchard/commit/73784af51859496eb16c0e24b88dae0682d4ef69" - }, - "date": 1665699718611, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4163232909, - "range": "± 42664991", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4166477219, - "range": "± 10937680", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5923176415, - "range": "± 23273496", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7691552558, - "range": "± 14435222", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33873220, - "range": "± 235486", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33818919, - "range": "± 311603", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 37801294, - "range": "± 926258", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 41850240, - "range": "± 321389", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1888885, - "range": "± 10469", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 157406, - "range": "± 125", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1888086, - "range": "± 4226", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 161930007, - "range": "± 45646", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 20040433, - "range": "± 10790", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2747495, - "range": "± 1315", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 19991345, - "range": "± 8114", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2705967, - "range": "± 1850", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 100084906, - "range": "± 127205", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13668911, - "range": "± 5994", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 99836502, - "range": "± 40618", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13462871, - "range": "± 4021", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 200101586, - "range": "± 46977", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27324580, - "range": "± 11956", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 199647338, - "range": "± 63493", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 26907239, - "range": "± 8490", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 579673, - "range": "± 1269", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 636481, - "range": "± 282", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "daira@jacaranda.org", - "name": "Daira Hopwood", - "username": "daira" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "591c4b89b9ae691d27239ac1fadaf13ab0c63272", - "message": "Merge pull request #351 from jarys/pub-value-commit-derive\n\nPublicize `ValueCommitment::derive` constructor", - "timestamp": "2022-10-18T20:19:19+01:00", - "tree_id": "ec2a3e3efbdb6f5b54b495f9559cd0abf4816e1f", - "url": "https://github.com/zcash/orchard/commit/591c4b89b9ae691d27239ac1fadaf13ab0c63272" - }, - "date": 1666121758257, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3834875352, - "range": "± 42253316", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3827452799, - "range": "± 17127473", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5476693302, - "range": "± 17005624", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7117720419, - "range": "± 17622082", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29792108, - "range": "± 1175176", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29811885, - "range": "± 594991", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 33240354, - "range": "± 202465", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36814105, - "range": "± 281511", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1591955, - "range": "± 876", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 132300, - "range": "± 237", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1597880, - "range": "± 10272", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 132644578, - "range": "± 49009", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 17123908, - "range": "± 23190", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2325096, - "range": "± 999", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16941856, - "range": "± 24417", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2290121, - "range": "± 942", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84864748, - "range": "± 38283", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11569252, - "range": "± 47074", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84660950, - "range": "± 46331", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11397785, - "range": "± 7393", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 169749740, - "range": "± 322282", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 23141414, - "range": "± 10781", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 169299766, - "range": "± 55527", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22772977, - "range": "± 7849", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 494777, - "range": "± 5429", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 546493, - "range": "± 365", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "daira@jacaranda.org", - "name": "Daira Hopwood", - "username": "daira" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "8123d896a94f529bc8cbc6a8f9dd39c00e61aafc", - "message": "Merge pull request #349 from jarys/value-commit-trapdoor-constructor\n\nAdd `ValueCommitTrapdoor::from_bytes` constructor", - "timestamp": "2022-10-18T21:32:22+01:00", - "tree_id": "6686cdeee12b40fc0642a95b301f18d66da5f704", - "url": "https://github.com/zcash/orchard/commit/8123d896a94f529bc8cbc6a8f9dd39c00e61aafc" - }, - "date": 1666126366899, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4953301240, - "range": "± 22477068", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4919132774, - "range": "± 47957127", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 7028694644, - "range": "± 26585957", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 9155463814, - "range": "± 68145532", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 38839664, - "range": "± 2201494", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 38224088, - "range": "± 2341208", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 42845668, - "range": "± 2348172", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 47869881, - "range": "± 2417546", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 2131777, - "range": "± 94107", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 177595, - "range": "± 5534", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1970646, - "range": "± 77555", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 171805202, - "range": "± 3585888", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 22351006, - "range": "± 594063", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 3062508, - "range": "± 77179", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 20917193, - "range": "± 580824", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2847225, - "range": "± 119829", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 112178416, - "range": "± 2990599", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 14628358, - "range": "± 552987", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 105318992, - "range": "± 3607634", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 14271842, - "range": "± 568223", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 224399589, - "range": "± 4136312", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 28975298, - "range": "± 1452472", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 210783075, - "range": "± 6175308", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 28523690, - "range": "± 1600681", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 618042, - "range": "± 14015", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 672002, - "range": "± 25874", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "ewillbefull@gmail.com", - "name": "ebfull", - "username": "ebfull" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "f1d2502d70043962fc3d41b823f003dd3382c93c", - "message": "Merge pull request #363 from zcash/release-0.3.0\n\nRelease of orchard 0.3.0", - "timestamp": "2022-10-19T12:59:56-06:00", - "tree_id": "2fb518f4103640259d5e61761473e476a049efa1", - "url": "https://github.com/zcash/orchard/commit/f1d2502d70043962fc3d41b823f003dd3382c93c" - }, - "date": 1666207162674, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4834600700, - "range": "± 164502616", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4789307539, - "range": "± 78130857", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 6773866028, - "range": "± 140822866", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 8543654363, - "range": "± 38188757", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 36037207, - "range": "± 1316580", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 35738735, - "range": "± 825658", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 40105913, - "range": "± 2182355", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 44707878, - "range": "± 5516065", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1927228, - "range": "± 11914", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 158763, - "range": "± 313", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1919954, - "range": "± 1489", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 168888987, - "range": "± 59158", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 20396997, - "range": "± 8573", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2772067, - "range": "± 1377", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 20363329, - "range": "± 7117", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2752742, - "range": "± 613", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 101884504, - "range": "± 42109", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13903816, - "range": "± 5980", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 101740795, - "range": "± 44783", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13699418, - "range": "± 8808", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 203752483, - "range": "± 424193", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 27791232, - "range": "± 12312", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 202033831, - "range": "± 52901", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 27379385, - "range": "± 10965", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 593624, - "range": "± 5101", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 655097, - "range": "± 316", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "d05b6cee9df7c4019509e2f54899b5979fb641b5", - "message": "Merge pull request #362 from zcash/batch-scanner-improvements\n\nBatch scanner improvements", - "timestamp": "2022-10-20T09:30:49-06:00", - "tree_id": "45c0b7bd0fb04c9de8adc3078a3e29e8956c28fe", - "url": "https://github.com/zcash/orchard/commit/d05b6cee9df7c4019509e2f54899b5979fb641b5" - }, - "date": 1666280999683, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3841058337, - "range": "± 19517856", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3847069732, - "range": "± 65317399", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5460368234, - "range": "± 17770838", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7105481141, - "range": "± 31609349", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 29709234, - "range": "± 811046", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 29852635, - "range": "± 527732", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 33299823, - "range": "± 806568", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 36694783, - "range": "± 784742", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1595439, - "range": "± 619", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 131160, - "range": "± 74", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1591679, - "range": "± 2714", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 1381234450, - "range": "± 1122724", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16863809, - "range": "± 10691", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2259270, - "range": "± 811", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16820433, - "range": "± 72849", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2224294, - "range": "± 2967", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84270273, - "range": "± 38387", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11241161, - "range": "± 4959", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84054794, - "range": "± 242902", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11068994, - "range": "± 5274", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 168513313, - "range": "± 62109", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 22460162, - "range": "± 8589", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168053757, - "range": "± 53722", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22118814, - "range": "± 7637", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 494371, - "range": "± 2799", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 546553, - "range": "± 4153", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "06cea3fa5356f09880c1c71e164ad165135ea441", - "message": "Merge pull request #366 from zingolabs/add_concrete_errors_for_spend_and_output_construction\n\nAdd concrete error types for add_spend and add_output", - "timestamp": "2022-12-08T14:19:32-07:00", - "tree_id": "d562ddee34565eb5de1797252d20635c202a796f", - "url": "https://github.com/zcash/orchard/commit/06cea3fa5356f09880c1c71e164ad165135ea441" - }, - "date": 1670535587556, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3985894751, - "range": "± 54802309", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3964093133, - "range": "± 82909488", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5572097520, - "range": "± 55245291", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7449738723, - "range": "± 210402367", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 32664320, - "range": "± 3429759", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 36561142, - "range": "± 4083040", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 40743922, - "range": "± 3826887", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 44008363, - "range": "± 3872774", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1592888, - "range": "± 1644", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 130926, - "range": "± 83", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1599108, - "range": "± 979", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 1396101205, - "range": "± 1759807", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16940379, - "range": "± 11477", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2258844, - "range": "± 973", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16893542, - "range": "± 9699", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2222641, - "range": "± 854", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84194077, - "range": "± 280835", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11238862, - "range": "± 7515", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84369371, - "range": "± 101454", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11064379, - "range": "± 11975", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 169337093, - "range": "± 105320", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 22475597, - "range": "± 19968", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168621368, - "range": "± 2271539", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22102510, - "range": "± 12497", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 493510, - "range": "± 655", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 545090, - "range": "± 1983", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "54b6e7437a795e67bed638d0d82045041add4089", - "message": "Merge pull request #367 from rex4539/typos\n\nFix typo", - "timestamp": "2023-01-03T12:46:31-07:00", - "tree_id": "a8c27e1579511126edb4f6d55584e22fe9860bcb", - "url": "https://github.com/zcash/orchard/commit/54b6e7437a795e67bed638d0d82045041add4089" - }, - "date": 1672776306586, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3926019342, - "range": "± 133146668", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3899174097, - "range": "± 6043828", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5511627530, - "range": "± 38016178", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7190129799, - "range": "± 17720312", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 31888617, - "range": "± 3455510", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 33292454, - "range": "± 3470246", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 39014380, - "range": "± 3454783", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 43998497, - "range": "± 3617442", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1600703, - "range": "± 3202", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 131501, - "range": "± 76", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1596127, - "range": "± 911", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 1399145257, - "range": "± 1141420", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 16909864, - "range": "± 8571", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2268487, - "range": "± 1012", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16894213, - "range": "± 4924", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2233746, - "range": "± 17113", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 84489507, - "range": "± 197992", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11290463, - "range": "± 5768", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84434925, - "range": "± 40857", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11119351, - "range": "± 4351", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 169019930, - "range": "± 290147", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 22571620, - "range": "± 9581", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 168833495, - "range": "± 46799", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22220553, - "range": "± 10887", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 493664, - "range": "± 2466", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 544858, - "range": "± 435", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "kris@nutty.land", - "name": "Kris Nuttycombe", - "username": "nuttycom" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "e2bfd99454b171e1a0c9fb3e128f09c023ea9700", - "message": "Merge pull request #365 from zingolabs/add_spends_and_outputs_getters_to_builder\n\nAdd spends/outputs getter fns to builders for use in change calculation", - "timestamp": "2023-01-03T14:57:06-07:00", - "tree_id": "87c672244ffcf6bb51114edfd4cb79bef9fc19d1", - "url": "https://github.com/zcash/orchard/commit/e2bfd99454b171e1a0c9fb3e128f09c023ea9700" - }, - "date": 1672784131466, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 3901348681, - "range": "± 93165193", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 3874108610, - "range": "± 18168842", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5521508391, - "range": "± 28763588", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7162630488, - "range": "± 31181737", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 33877888, - "range": "± 3793757", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 31426887, - "range": "± 3698998", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 38650696, - "range": "± 3921296", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 44089329, - "range": "± 3724610", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1619366, - "range": "± 7335", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 132030, - "range": "± 235", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1600185, - "range": "± 409", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 1400827181, - "range": "± 867419", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 17103499, - "range": "± 23689", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2292363, - "range": "± 840", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 16920584, - "range": "± 8623", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2233617, - "range": "± 791", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 85419884, - "range": "± 156900", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 11312535, - "range": "± 4632", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 84534693, - "range": "± 29222", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 11118684, - "range": "± 5800", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 170803694, - "range": "± 131798", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 22584325, - "range": "± 15747", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 169041385, - "range": "± 35207", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 22216396, - "range": "± 6396", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 493741, - "range": "± 181", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 544453, - "range": "± 257", - "unit": "ns/iter" - } - ] - }, - { - "commit": { - "author": { - "email": "jack@electriccoin.co", - "name": "str4d", - "username": "str4d" - }, - "committer": { - "email": "noreply@github.com", - "name": "GitHub", - "username": "web-flow" - }, - "distinct": true, - "id": "c48247dd34c53af43697e97837c81a5b37ad98c8", - "message": "Merge pull request #398 from zcash/update_incrementalmerkletree\n\nMigrate to `incrementalmerkletree 0.5`", - "timestamp": "2023-09-08T19:21:50+01:00", - "tree_id": "c10860dfeefd74df2eb5aa69d15862038ba02bf6", - "url": "https://github.com/zcash/orchard/commit/c48247dd34c53af43697e97837c81a5b37ad98c8" - }, - "date": 1694198468918, - "tool": "cargo", - "benches": [ - { - "name": "proving/bundle/1", - "value": 4023237690, - "range": "± 585274572", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/2", - "value": 4014465821, - "range": "± 23384448", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/3", - "value": 5732875599, - "range": "± 19335968", - "unit": "ns/iter" - }, - { - "name": "proving/bundle/4", - "value": 7460144563, - "range": "± 33218225", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/1", - "value": 39482294, - "range": "± 3655218", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/2", - "value": 39973588, - "range": "± 4019443", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/3", - "value": 43613550, - "range": "± 3996511", - "unit": "ns/iter" - }, - { - "name": "verifying/bundle/4", - "value": 52091076, - "range": "± 6468532", - "unit": "ns/iter" - }, - { - "name": "note-decryption/valid", - "value": 1869522, - "range": "± 6016", - "unit": "ns/iter" - }, - { - "name": "note-decryption/invalid", - "value": 154818, - "range": "± 184", - "unit": "ns/iter" - }, - { - "name": "note-decryption/compact-valid", - "value": 1866776, - "range": "± 738", - "unit": "ns/iter" - }, - { - "name": "compact-note-decryption/invalid", - "value": 1632295700, - "range": "± 1481967", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/10", - "value": 19745695, - "range": "± 8122", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/10", - "value": 2666356, - "range": "± 2266", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/10", - "value": 19712124, - "range": "± 49186", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/10", - "value": 2623659, - "range": "± 1961", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/50", - "value": 98656814, - "range": "± 254464", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/50", - "value": 13189392, - "range": "± 9277", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/50", - "value": 98500632, - "range": "± 25318", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/50", - "value": 13008188, - "range": "± 9583", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/valid/100", - "value": 197253671, - "range": "± 102026", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/invalid/100", - "value": 26342431, - "range": "± 51949", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-valid/100", - "value": 196914485, - "range": "± 95729", - "unit": "ns/iter" - }, - { - "name": "batch-note-decryption/compact-invalid/100", - "value": 25980563, - "range": "± 12236", - "unit": "ns/iter" - }, - { - "name": "derive_fvk", - "value": 565130, - "range": "± 5193", - "unit": "ns/iter" - }, - { - "name": "default_address", - "value": 606863, - "range": "± 1882", - "unit": "ns/iter" - } - ] - } - ] - } -} \ No newline at end of file diff --git a/dev/bench/index.html b/dev/bench/index.html deleted file mode 100644 index 3a653b2c..00000000 --- a/dev/bench/index.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - Benchmarks - - - - -
- - - - - - - diff --git a/highlight.css b/highlight.css index ab8c49c6..ba57b82b 100644 --- a/highlight.css +++ b/highlight.css @@ -1,14 +1,18 @@ -/* Base16 Atelier Dune Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ +/* + * An increased contrast highlighting scheme loosely based on the + * "Base16 Atelier Dune Light" theme by Bram de Haan + * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) + * Original Base16 color scheme by Chris Kempson + * (https://github.com/chriskempson/base16) + */ -/* Atelier-Dune Comment */ +/* Comment */ .hljs-comment, .hljs-quote { - color: #AAA; + color: #575757; } -/* Atelier-Dune Red */ +/* Red */ .hljs-variable, .hljs-template-variable, .hljs-attribute, @@ -19,10 +23,10 @@ .hljs-name, .hljs-selector-id, .hljs-selector-class { - color: #d73737; + color: #d70025; } -/* Atelier-Dune Orange */ +/* Orange */ .hljs-number, .hljs-meta, .hljs-built_in, @@ -30,34 +34,33 @@ .hljs-literal, .hljs-type, .hljs-params { - color: #b65611; + color: #b21e00; } -/* Atelier-Dune Green */ +/* Green */ .hljs-string, .hljs-symbol, .hljs-bullet { - color: #60ac39; + color: #008200; } -/* Atelier-Dune Blue */ +/* Blue */ .hljs-title, .hljs-section { - color: #6684e1; + color: #0030f2; } -/* Atelier-Dune Purple */ +/* Purple */ .hljs-keyword, .hljs-selector-tag { - color: #b854d4; + color: #9d00ec; } .hljs { display: block; overflow-x: auto; - background: #f1f1f1; - color: #6e6b5e; - padding: 0.5em; + background: #f6f7f6; + color: #000; } .hljs-emphasis { diff --git a/index.html b/index.html index ad176cc3..0fc1bc60 100644 --- a/index.html +++ b/index.html @@ -1,40 +1,27 @@ - + Orchard - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/print.html b/print.html index 4153750d..03964ed6 100644 --- a/print.html +++ b/print.html @@ -1,42 +1,28 @@ - + The Orchard Book - - - - + - - - - + - - - - - - - - @@ -44,19 +30,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/searcher.js b/searcher.js index acf3d50c..d2b0aeed 100644 --- a/searcher.js +++ b/searcher.js @@ -296,7 +296,7 @@ window.search = window.search || {}; } if (url.params.hasOwnProperty(URL_MARK_PARAM)) { - var words = url.params[URL_MARK_PARAM].split(' '); + var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' '); marker.mark(words, { exclude: mark_exclude }); @@ -427,6 +427,7 @@ window.search = window.search || {}; delete url.params[URL_MARK_PARAM]; url.hash = ""; } else { + delete url.params[URL_MARK_PARAM]; delete url.params[URL_SEARCH_PARAM]; } // A new search will also add a new history item, so the user can go back diff --git a/searchindex.js b/searchindex.js index 17715434..d095245f 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Object.assign(window.search, {"doc_urls":["index.html#orchard---cratesio","index.html#documentation","index.html#license","concepts.html#concepts","concepts/preliminaries.html#preliminaries","user.html#user-documentation","user/keys.html#creating-keys-and-addresses","user/creating-notes.html#creating-notes","user/spending-notes.html#spending-notes","user/integration.html#integration-into-an-existing-chain","design.html#design","design.html#general-design-notes","design.html#requirements","design.html#non-requirements","design.html#open-issues","design.html#note-structure","design.html#typed-variables-vs-byte-encodings","design/keys.html#keys-and-addresses","design/keys.html#hierarchical-deterministic-wallets","design/actions.html#actions","design/actions.html#memo-fields","design/commitments.html#commitments","design/commitment-tree.html#commitment-tree","design/commitment-tree.html#uncommitted-leaves","design/commitment-tree.html#considered-alternatives","design/nullifiers.html#nullifiers","design/nullifiers.html#security-properties","design/nullifiers.html#considered-alternatives","design/nullifiers.html#rationale","design/nullifiers.html#use-of-ρ","design/nullifiers.html#use-of-ψ","design/nullifiers.html#use-of-cm","design/signatures.html#signatures","design/circuit.html#circuit","design/circuit/gadgets.html#gadgets","design/circuit/commit-ivk.html#commitivk","design/circuit/commit-ivk.html#message-decomposition","design/circuit/commit-ivk.html#bit-length-constraints","design/circuit/commit-ivk.html#decomposition-constraints","design/circuit/commit-ivk.html#canonicity-checks","design/circuit/commit-ivk.html#ak-with-b11ak2254","design/circuit/commit-ivk.html#nk-with-d11nk2254","design/circuit/commit-ivk.html#region-layout","design/circuit/note-commit.html#notecommit","design/circuit/note-commit.html#message-decomposition","design/circuit/note-commit.html#message-piece-decomposition","design/circuit/note-commit.html#bb0b1b2b3","design/circuit/note-commit.html#dd0d1d2d3","design/circuit/note-commit.html#ee0e1","design/circuit/note-commit.html#gg0g1g2","design/circuit/note-commit.html#hh0h1h2","design/circuit/note-commit.html#field-element-checks","design/circuit/note-commit.html#xgd-with-b11xgd2254","design/circuit/note-commit.html#xpkd-with-d01xpkd2254","design/circuit/note-commit.html#vd228d3258e0","design/circuit/note-commit.html#ρ-with-g01ρ2254","design/circuit/note-commit.html#ψ-with-h11ψ2254","design/circuit/note-commit.html#y-coordinate-checks","design/circuit/note-commit.html#ygd-with-k31ygd2254","design/circuit/note-commit.html#ypkd"],"index":{"documentStore":{"docInfo":{"0":{"body":3,"breadcrumbs":2,"title":2},"1":{"body":4,"breadcrumbs":1,"title":1},"10":{"body":0,"breadcrumbs":1,"title":1},"11":{"body":0,"breadcrumbs":3,"title":3},"12":{"body":7,"breadcrumbs":1,"title":1},"13":{"body":21,"breadcrumbs":2,"title":2},"14":{"body":30,"breadcrumbs":2,"title":2},"15":{"body":5,"breadcrumbs":2,"title":2},"16":{"body":61,"breadcrumbs":5,"title":5},"17":{"body":325,"breadcrumbs":3,"title":2},"18":{"body":243,"breadcrumbs":4,"title":3},"19":{"body":123,"breadcrumbs":2,"title":1},"2":{"body":46,"breadcrumbs":1,"title":1},"20":{"body":35,"breadcrumbs":3,"title":2},"21":{"body":137,"breadcrumbs":2,"title":1},"22":{"body":47,"breadcrumbs":3,"title":2},"23":{"body":133,"breadcrumbs":3,"title":2},"24":{"body":131,"breadcrumbs":3,"title":2},"25":{"body":75,"breadcrumbs":2,"title":1},"26":{"body":212,"breadcrumbs":3,"title":2},"27":{"body":133,"breadcrumbs":3,"title":2},"28":{"body":62,"breadcrumbs":2,"title":1},"29":{"body":211,"breadcrumbs":2,"title":1},"3":{"body":0,"breadcrumbs":1,"title":1},"30":{"body":134,"breadcrumbs":2,"title":1},"31":{"body":132,"breadcrumbs":3,"title":2},"32":{"body":24,"breadcrumbs":2,"title":1},"33":{"body":0,"breadcrumbs":2,"title":1},"34":{"body":44,"breadcrumbs":3,"title":1},"35":{"body":0,"breadcrumbs":3,"title":1},"36":{"body":103,"breadcrumbs":4,"title":2},"37":{"body":17,"breadcrumbs":5,"title":3},"38":{"body":68,"breadcrumbs":4,"title":2},"39":{"body":87,"breadcrumbs":4,"title":2},"4":{"body":0,"breadcrumbs":2,"title":1},"40":{"body":55,"breadcrumbs":4,"title":2},"41":{"body":62,"breadcrumbs":4,"title":2},"42":{"body":12,"breadcrumbs":4,"title":2},"43":{"body":0,"breadcrumbs":3,"title":1},"44":{"body":176,"breadcrumbs":4,"title":2},"45":{"body":40,"breadcrumbs":5,"title":3},"46":{"body":16,"breadcrumbs":3,"title":1},"47":{"body":29,"breadcrumbs":3,"title":1},"48":{"body":15,"breadcrumbs":3,"title":1},"49":{"body":29,"breadcrumbs":3,"title":1},"5":{"body":0,"breadcrumbs":2,"title":2},"50":{"body":14,"breadcrumbs":3,"title":1},"51":{"body":102,"breadcrumbs":5,"title":3},"52":{"body":64,"breadcrumbs":4,"title":2},"53":{"body":65,"breadcrumbs":4,"title":2},"54":{"body":5,"breadcrumbs":3,"title":1},"55":{"body":65,"breadcrumbs":3,"title":1},"56":{"body":71,"breadcrumbs":3,"title":1},"57":{"body":96,"breadcrumbs":5,"title":3},"58":{"body":68,"breadcrumbs":4,"title":2},"59":{"body":8,"breadcrumbs":3,"title":1},"6":{"body":0,"breadcrumbs":5,"title":3},"7":{"body":0,"breadcrumbs":4,"title":2},"8":{"body":0,"breadcrumbs":4,"title":2},"9":{"body":0,"breadcrumbs":5,"title":3}},"docs":{"0":{"body":"Requires Rust 1.56.1+.","breadcrumbs":"orchard Crates.io","id":"0","title":"orchard Crates.io"},"1":{"body":"The Orchard Book Crate documentation","breadcrumbs":"Documentation","id":"1","title":"Documentation"},"10":{"body":"","breadcrumbs":"Design","id":"10","title":"Design"},"11":{"body":"","breadcrumbs":"General design notes","id":"11","title":"General design notes"},"12":{"body":"Keep the design close to Sapling, while eliminating aspects we don't like.","breadcrumbs":"Requirements","id":"12","title":"Requirements"},"13":{"body":"Delegated proving with privacy from the prover. We know how to do this, but it would require a discrete log equality proof, and the most efficient way to do this would be to do RedDSA and this at the same time, which means more work for e.g. hardware wallets.","breadcrumbs":"Non-requirements","id":"13","title":"Non-requirements"},"14":{"body":"Should we have one memo per output, or one memo per transaction, or 0..n memos? Variable, or (1 or n), is a potential privacy leak. Need to consider the privacy issue related to light clients requesting individual memos vs being able to fetch all memos.","breadcrumbs":"Open issues","id":"14","title":"Open issues"},"15":{"body":"TODO: UDAs: arbitrary vs whitelisted","breadcrumbs":"Note structure","id":"15","title":"Note structure"},"16":{"body":"For Sapling, we have encountered multiple places where the specification uses typed variables to define the consensus rules, but the C++ implementation in zcashd relied on byte encodings to implement them. This resulted in subtly-different consensus rules being deployed than were intended, for example where a particular type was not round-trip encodable. In Orchard, we avoid this by defining the consensus rules in terms of the byte encodings of all variables, and being explicit about any types that are not round-trip encodable. This makes consensus compatibility between strongly-typed implementations (such as this crate) and byte-oriented implementations easier to achieve.","breadcrumbs":"Typed variables vs byte encodings","id":"16","title":"Typed variables vs byte encodings"},"17":{"body":"Orchard keys and payment addresses are structurally similar to Sapling. The main change is that Orchard keys use the Pallas curve instead of Jubjub, in order to enable the future use of the Pallas-Vesta curve cycle in the Orchard protocol. (We already use Vesta as the curve on which Halo 2 proofs are computed, but this doesn't yet require a cycle.) Using the Pallas curve and making the most efficient use of the Halo 2 proof system involves corresponding changes to the key derivation process, such as using Sinsemilla for Pallas-efficient commitments. We also take the opportunity to remove all uses of expensive general-purpose hashes (such as BLAKE2s) from the circuit. We make several structural changes, building on the lessons learned from Sapling: The nullifier private key nsk is removed. Its purpose in Sapling was as defense-in-depth, in case RedDSA was found to have weaknesses; an adversary who could recover ask would not be able to spend funds. In practice it has not been feasible to manage nsk much more securely than a full viewing key, as the computational power required to generate Sapling proofs has made it necessary to perform this step on the same device that is creating the overall transaction (rather than on a more constrained device like a hardware wallet). We are also more confident in RedDSA now. nk is now a field element instead of a curve point, making it more efficient to generate nullifiers. ovk is now derived from fvk, instead of being derived in parallel. This places it in a similar position within the key structure to ivk, and also removes an issue where two full viewing keys could be constructed that have the same ivk but different ovks. Users still have control over whether ovk is used when constructing a transaction. All diversifiers now result in valid payment addresses, due to group hashing into Pallas being specified to be infallible. This removes significant complexity from the use cases for diversified addresses. The fact that Pallas is a prime-order curve simplifies the protocol and removes the need for cofactor multiplication in key agreement. Unlike Sapling, we define public (including ephemeral) and private keys used for note encryption to exclude the zero point and the zero scalar. Without this change, the implementation of the Orchard Action circuit would need special cases for the zero point, since Pallas is a short Weierstrass rather than an Edwards curve. This also has the advantage of ensuring that the key agreement has \"contributory behaviour\" — that is, if either party contributes a random scalar, then the shared secret will be random to an observer who does not know that scalar and cannot break Diffie–Hellman. Other than the above, Orchard retains the same design rationale for its keys and addresses as Sapling. For example, diversifiers remain at 11 bytes, so that a raw Orchard address is the same length as a raw Sapling address. Orchard payment addresses do not have a stand-alone string encoding. Instead, we define \"unified addresses\" that can bundle together addresses of different types, including Orchard. Unified addresses have a Human-Readable Part of \"u\" on Mainnet, i.e. they will have the prefix \"u1\". For specifications of this and other formats (e.g. for Orchard viewing and spending keys), see section 5.6.4 of the NU5 protocol specification [#NU5-orchardencodings].","breadcrumbs":"Design » Keys and addresses","id":"17","title":"Keys and addresses"},"18":{"body":"When designing Sapling, we defined a BIP 32 -like mechanism for generating hierarchical deterministic wallets in ZIP 32 . We decided at the time to stick closely to the design of BIP 32, on the assumption that there were Bitcoin use cases that used both hardened and non-hardened derivation that we might not be aware of. This decision created significant complexity for Sapling: we needed to handle derivation separately for each component of the expanded spending key and full viewing key (whereas for transparent addresses there is only a single component in the spending key). Non-hardened derivation enables creating a multi-level path of child addresses below some parent address, without involving the parent spending key. The primary use case for this is HD wallets for transparent addresses, which use the following structure defined in BIP 44 : (H) BIP 44 (H) Coin type: Zcash (H) Account 0 (N) Normal addresses (N) Address 0 (N) Address 1... (N) Change addresses (N) Change address 0 (N) Change address 1... (H) Account 1... Shielded accounts do not require separating change addresses from normal addresses, because addresses are not revealed in transactions. Similarly, there is also no need to generate a fresh spending key for every transaction, and in fact this would cause a linear slow-down in wallet scanning. But for users who do want to generate multiple addresses per account, they can generate the following structure, which does not use non-hardened derivation: (H) ZIP 32 (H) Coin type: Zcash (H) Account 0 Diversified address 0 Diversified address 1... (H) Account 1... Non-hardened derivation is therefore only required for use-cases that require the ability to derive more than one child layer of addresses. However, in the years since Sapling was deployed, we have not seen any such use cases appear. Therefore, for Orchard we only define hardened derivation, and do so with a much simpler design than ZIP 32. All derivations produce an opaque binary spending key, from which the keys and addresses are then derived. As a side benefit, this makes key formats shorter. (The formats that will actually be used in practice for Orchard will correspond to the simpler Sapling formats in the protocol specification, rather than the longer and more complicated \"extended\" ones defined by ZIP 32.)","breadcrumbs":"Design » Hierarchical deterministic wallets","id":"18","title":"Hierarchical deterministic wallets"},"19":{"body":"In Sprout, we had a single proof that represented two spent notes and two new notes. This was necessary in order to facilitate spending multiple notes in a single transaction (to balance value, an output of one JoinSplit could be spent in the next one), but also provided a minimal level of arity-hiding: single-JoinSplit transactions all looked like 2-in 2-out transactions, and in multi-JoinSplit transactions each JoinSplit looked like a 1-in 1-out. In Sapling, we switched to using value commitments to balance the transaction, removing the min-2 arity requirement. We opted for one proof per spent note and one (much simpler) proof per output note, which greatly improved the performance of generating outputs, but removed any arity-hiding from the proofs (instead having the transaction builder pad transactions to 1-in, 2-out). For Orchard, we take a combined approach: we define an Orchard transaction as containing a bundle of actions, where each action is both a spend and an output. This provides the same inherent arity-hiding as multi-JoinSplit Sprout, but using Sapling value commitments to balance the transaction without doubling its size.","breadcrumbs":"Design » Actions","id":"19","title":"Actions"},"2":{"body":"Copyright 2020-2022 The Electric Coin Company. You may use this package under the Bootstrap Open Source Licence, version 1.0, or at your option, any later version. See the file COPYING for more details, and LICENSE-BOSL for the terms of the Bootstrap Open Source Licence, version 1.0. The purpose of the BOSL is to allow commercial improvements to the package while ensuring that all improvements are open source. See here for why the BOSL exists.","breadcrumbs":"License","id":"2","title":"License"},"20":{"body":"Each Orchard action has a memo field for its corresponding output, as with Sprout and Sapling. We did at one point consider having a single Orchard memo field per transaction, and/or having a mechanism for enabling multiple recipients to decrypt the same memo, but these were decided against in order to keep the overall design simpler.","breadcrumbs":"Design » Memo fields","id":"20","title":"Memo fields"},"21":{"body":"As in Sapling, we require two kinds of commitment schemes in Orchard: HomomorphicCommit is a linearly homomorphic commitment scheme with perfect hiding, and strong binding reducible to DL. Commit and ShortCommit are commitment schemes with perfect hiding, and strong binding reducible to DL. By \"strong binding\" we mean that the scheme is collision resistant on the input and randomness. We instantiate HomomorphicCommit with a Pedersen commitment, and use it for value commitments: cv=HomomorphicCommitrcvcv​(v) We instantiate Commit and ShortCommit with Sinsemilla, and use them for all other commitments: ivk=ShortCommitrivkivk​(ak,nk) cm=Commitrcmcm​(rest of note) This is the same split (and rationale) as in Sapling, but using the more PLONK-efficient Sinsemilla instead of Bowe--Hopwood Pedersen hashes. Note that for ivk, we also deviate from Sapling in two ways: We use ShortCommit to derive ivk instead of a full PRF. This removes an unnecessary (large) PRF primitive from the circuit, at the cost of requiring rivk to be part of the full viewing key. We define ivk as an integer in [1,qP​); that is, we exclude ivk=0. For Sapling, we relied on BLAKE2s to make ivk=0 infeasible to produce, but it was still technically possible. For Orchard, we get this by construction: 0 is not a valid x-coordinate for any Pallas point. SinsemillaShortCommit internally maps points to field elements by replacing the identity (which has no affine coordinates) with 0. But SinsemillaCommit is defined using incomplete addition, and thus will never produce the identity.","breadcrumbs":"Design » Commitments","id":"21","title":"Commitments"},"22":{"body":"The commitment tree structure for Orchard is identical to Sapling: A single global commitment tree of fixed depth 32. Note commitments are appended to the tree in-order from the block. Valid Orchard anchors correspond to the global tree state at block boundaries (after all commitments from a block have been appended, and before any commitments from the next block have been appended). The only difference is that we instantiate MerkleCRHOrchard with Sinsemilla (whereas MerkleCRHSapling used a Bowe--Hopwood Pedersen hash).","breadcrumbs":"Design » Commitment tree","id":"22","title":"Commitment tree"},"23":{"body":"The fixed-depth incremental Merkle trees that we use (in Sprout and Sapling, and again in Orchard) require specifying an \"empty\" or \"uncommitted\" leaf - a value that will never be appended to the tree as a regular leaf. For Sprout (and trees composed of the outputs of bit-twiddling hash functions), we use the all-zeroes array; the probability of a real note having a colliding note commitment is cryptographically negligible. For Sapling, where leaves are u-coordinates of Jubjub points, we use the value 1 which is not the u-coordinate of any Jubjub point. Orchard note commitments are the x-coordinates of Pallas points; thus we take the same approach as Sapling, using a value that is not the x-coordinate of any Pallas point as the uncommitted leaf value. We use the value 2 for both Pallas and Vesta, because 23+5 is not a square in either Fp​ or Fq​: sage: p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001\nsage: q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001\nsage: EllipticCurve(GF(p), [0, 5]).count_points() == q\nTrue\nsage: EllipticCurve(GF(q), [0, 5]).count_points() == p\nTrue\nsage: Mod(13, p).is_square()\nFalse\nsage: Mod(13, q).is_square()\nFalse Note: There are also no Pallas points with x-coordinate 0, but we map the identity to (0,0) within the circuit. Although SinsemillaCommit cannot return the identity (the incomplete addition would return ⊥ instead), it would arguably be confusing to rely on that.","breadcrumbs":"Design » Uncommitted leaves","id":"23","title":"Uncommitted leaves"},"24":{"body":"We considered splitting the commitment tree into several sub-trees: Bundle tree, that accumulates the commitments within a single bundle (and thus a single transaction). Block tree, that accumulates the bundle tree roots within a single block. Global tree, that accumulates the block tree roots. Each of these trees would have had a fixed depth (necessary for being able to create proofs). Chains that integrated Orchard could have decoupled the limits on commitments-per-subtree from higher-layer constraints like block size, by enabling their blocks and transactions to be structured internally as a series of Orchard blocks or txs (e.g. a Zcash block would have contained a Vec, that each were appended in-order). The motivation for considering this change was to improve the lives of light client wallet developers. When a new note is received, the wallet derives its incremental witness from the state of the global tree at the point when the note's commitment is appended; this incremental state then needs to be updated with every subsequent commitment in the block in-order. Wallets can't get help from the server to create these for new notes without leaking the specific note that was received. We decided that this was too large a change from Sapling, and that it should be possible to improve the Incremental Merkle Tree implementation to work around the efficiency issues without domain-separating the tree.","breadcrumbs":"Design » Considered alternatives","id":"24","title":"Considered alternatives"},"25":{"body":"The nullifier design we use for Orchard is nf=ExtractP​([(Fnk​(ρ)+ψ)modp]G+cm), where: F is a keyed circuit-efficient PRF (such as Rescue or Poseidon). ρ is unique to this output. As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. Given that an action consists of a single spend and a single output, we set ρ to be the nullifier of the spent note. ψ is sender-controlled randomness. It is not required to be unique, and in practice is derived from both ρ and a sender-selected random value rseed: ψ=KDFψ(ρ,rseed). G is a fixed independent base. ExtractP​ extracts the x-coordinate of a Pallas curve point. This gives a note structure of (addr,v,ρ,ψ,rcm). The note plaintext includes rseed in place of ψ and rcm, and omits ρ (which is a public part of the action).","breadcrumbs":"Design » Nullifiers","id":"25","title":"Nullifiers"},"26":{"body":"We care about several security properties for our nullifiers: Balance: can I forge money? Note Privacy: can I gain information about notes only from the public block chain? This describes notes sent in-band. Note Privacy (OOB): can I gain information about notes sent out-of-band, only from the public block chain? In this case, we assume privacy of the channel over which the note is sent, and that the adversary does not have access to any notes sent to the same address which are then spent (so that the nullifier is on the block chain somewhere). Spend Unlinkability: given the incoming viewing key for an address, and not the full viewing key, can I (possibly the sender) detect spends of any notes sent to that address? We're giving ivk to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address. Faerie Resistance: can I perform a Faerie Gold attack (i.e. cause notes to be accepted that are unspendable)? We're giving the full viewing key to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address, and be able to derive every nullifier. We assume (and instantiate elsewhere) the following primitives: GH is a cryptographic hash into the group (such as BLAKE2s with simplified SWU), used to derive all fixed independent bases. E is an elliptic curve (such as Pallas). KDF is the note encryption key derivation function. For our chosen design, our desired security properties rely on the following assumptions: BalanceNote PrivacyNote Privacy (OOB)Spend UnlinkabilityFaerie Resistance​DLE​HashDHEKDF​Near perfect‡DDHE†​∨PRFF​DLE​​​ HashDHEKDF​ is computational Diffie-Hellman using KDF for the key derivation, with one-time ephemeral keys. This assumption is heuristically weaker than DDHE​ but stronger than DLE​. We omit ROGH​ as a security assumption because we only rely on the random oracle applied to fixed inputs defined by the protocol, i.e. to generate the fixed base G, not to attacker-specified inputs. † We additionally assume that for any input x, {Fnk​(x):nk∈E} gives a scalar in an adequate range for DDHE​. (Otherwise, F could be trivial, e.g. independent of nk.) ‡ Statistical distance <2−167.8 from perfect.","breadcrumbs":"Design » Security properties","id":"26","title":"Security properties"},"27":{"body":"⚠ Caution: be skeptical of the claims in this table about what problem(s) each security property depends on. They may not be accurate and are definitely not fully rigorous. The entries in this table omit the application of ExtractP​, which is an optimization to halve the nullifier length. That optimization requires its own security analysis, but because it is a deterministic mapping, only Faerie Resistance could be affected by it. nf[nk][θ]H[nk]H+[rnf]IHash([nk][θ]H)Hash([nk]H+[rnf]I)[Fnk​(ψ)][θ]H[Fnk​(ψ)]H+[rnf]I[Fnk​(ψ)]G+[θ]H[Fnk​(ψ)]H+cm[Fnk​(ρ,ψ)]G+cm[Fnk​(ρ)]G+cm[Fnk​(ρ,ψ)]Gv​+[rnf]I[Fnk​(ρ)]Gv​+[rnf]I[(Fnk​(ρ)+ψ)modp]Gv​[Fnk​(ρ,ψ)]G+Commitrnfnf​(v,ρ)[Fnk​(ρ)]G+Commitrnfnf​(v,ρ)​Note(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,rnf,ψ,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,ψ,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)​BalanceDLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​​Note PrivacyHashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​​Note Priv OOBPerfectPerfectPerfectPerfectPerfectPerfectPerfectDDHE†​DDHE†​DDHE†​PerfectPerfectNear perfect‡PerfectPerfect​Spend UnlinkabilityDDHE​DDHE​DDHE​∨PreHash​DDHE​∨PreHash​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​​Faerie ResistanceROGH​∧DLE​ROGH​∧DLE​CollHash​∧ROGH​∧DLE​CollHash​∧ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​DLE​DLE​CollF​∧DLE​CollF​∧DLE​brokenDLE​DLE​​Reason not to useNo SU for DL-breakingNo SU for DL-breakingCollHash​ for FRCollHash​ for FRPerf. (2 var-base)Perf. (1 var+1 fix-base)Perf. (1 var+1 fix-base)NP(OOB) not perfectNP(OOB) not perfectNP(OOB) not perfectCollF​ for FRCollF​ for FRbroken for FRPerf. (2 fix-base)Perf. (2 fix-base)​​ In the above alternatives: Hash is a keyed circuit-efficient hash (such as Rescue). I is an fixed independent base, independent of G and any others returned by GH. Gv​ is a pair of fixed independent bases (independent of all others), where the specific choice of base depends on whether the note has zero value. H is a base unique to this output. For non-zero-valued notes, H=GH(ρ). As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. For zero-valued notes, H is constrained by the circuit to a fixed base independent of I and any others returned by GH.","breadcrumbs":"Design » Considered alternatives","id":"27","title":"Considered alternatives"},"28":{"body":"In order to satisfy the Balance security property, we require that the circuit must be able to enforce that only one nullifier is accepted for a given note. As in Sprout and Sapling, we achieve this by ensuring that the nullifier deterministically depends only on values committed to (directly or indirectly) by the note commitment. As in Sapling, this involves arguing that: There can be only one ivk for a given addr. This is true because the circuit checks that pkd​=[ivk]gd​, and the mapping ivk↦[ivk]gd​ is an injection for any gd​. (ivk is in the base field of E, which must be smaller than its scalar field, as is the case for Pallas.) There can be only one nk for a given ivk. This is true because the circuit checks that ivk=ShortCommitrivkivk​(ak,nk) where ShortCommit is binding (see Commitments ).","breadcrumbs":"Design » Rationale","id":"28","title":"Rationale"},"29":{"body":"Faerie Resistance requires that nullifiers be unique. This is primarily achieved by taking a unique value (checked for uniqueness by the public consensus rules) as an input to the nullifier. However, it is also necessary to ensure that the transformations applied to this value preserve its uniqueness. Meanwhile, to achieve Spend Unlinkability , we require that the nullifier does not reveal any information about the unique value it is derived from. The design alternatives fall into two categories in terms of how they balance these requirements: Publish a unique value ρ at note creation time, and blind that value within the nullifier computation. This is similar to the approach taken in Sprout and Sapling, which both implemented nullifiers as PRF outputs; Sprout uses the compression function from SHA-256, while Sapling uses BLAKE2s. Derive a unique base H from some unique value, publish that unique base at note creation time, and then blind the base (either additively or multiplicatively) during nullifier computation. For Spend Unlinkability , the only value unknown to the adversary is nk, and the cryptographic assumptions only involve the first term (other terms like cm or [rnf]I cannot be extracted directly from the observed nullifiers, but can be subtracted from them). We therefore ensure that the first term does not commit directly to the note (to avoid a DL-breaking adversary from immediately breaking SU ). We were considering using a design involving H with the goal of eliminating all usages of a PRF inside the circuit, for two reasons: Instantiating PRFF​ with a traditional hash function is expensive in the circuit. We didn't want to solely rely on an algebraic hash function satisfying PRFF​ to achieve Spend Unlinkability . However, those designs rely on both ROGH​ and DLE​ for Faerie Resistance , while still requiring DDHE​ for Spend Unlinkability . (There are two designs for which this is not the case, but they rely on DDHE†​ for Note Privacy (OOB) which was not acceptable). By contrast, several designs involving ρ (including the chosen design) have weaker assumptions for Faerie Resistance (only relying on DLE​), and Spend Unlinkability does not require PRFF​ to hold: they can fall back on the same DDHE​ assumption as the H designs (along with an additional assumption about the output of F which is easily satisfied).","breadcrumbs":"Design » Use of ρ","id":"29","title":"Use of ρ"},"3":{"body":"","breadcrumbs":"Concepts","id":"3","title":"Concepts"},"30":{"body":"Most of the designs include either a multiplicative blinding term [θ]H, or an additive blinding term [rnf]I, in order to achieve perfect Note Privacy (OOB) (to an adversary who does not know the note). The chosen design is effectively using [ψ]G for this purpose; a DL-breaking adversary only learns Fnk​(ρ)+ψ(modp). This reduces Note Privacy (OOB) from perfect to statistical, but given that ψ is from a distribution statistically close to uniform on [0,q), this is statistically close to better than 2−128. The benefit is that it does not require an additional scalar multiplication, making it more efficient inside the circuit. ψ's derivation has two motivations: Deriving from a random value rseed enables multiple derived values to be conveyed to the recipient within an action (such as the ephemeral secret esk, per ZIP 212 ), while keeping the note plaintext short. Mixing ρ into the derivation ensures that the sender can't repeat ψ across two notes, which could have enabled spend linkability attacks in some designs. The note that is committed to, and which the circuit takes as input, only includes ψ (i.e. the circuit does not check the derivation from rseed). However, an adversarial sender is still constrained by this derivation, because the recipient recomputes ψ during note decryption. If an action were created using an arbitrary ψ (for which the adversary did not have a corresponding rseed), the recipient would derive a note commitment that did not match the action's commitment field, and reject it (as in Sapling).","breadcrumbs":"Design » Use of ψ","id":"30","title":"Use of ψ"},"31":{"body":"The nullifier commits to the note value via cm for two reasons: It domain-separates nullifiers for zero-valued notes from other notes. This is necessary because we do not require zero-valued notes to exist in the commitment tree. Designs that bind the nullifier to Fnk​(ρ) require CollF​ to achieve Faerie Resistance (and similarly where Hash is applied to a value derived from H). Adding cm to the nullifier avoids this assumption: all of the bases used to derive cm are fixed and independent of G, and so the nullifier can be viewed as a Pedersen hash where the input includes ρ directly. The Commitnf variants were considered to avoid directly depending on cm (which in its native type is a base field element, not a group element). We decided instead to follow Sapling by defining an intermediate representation of cm as a group element, that is only used in nullifier computation. The circuit already needs to compute cm, so this improves performance by removing We also considered variants that used a choice of fixed bases Gv​ to provide domain separation for zero-valued notes. The most performant design (similar to the chosen design) does not achieve Faerie Resistance for an adversary that knows the recipient's full viewing key (ψ could be brute-forced to cancel out Fnk​(ρ), causing a collision), and the other variants require assuming CollF​ as mentioned above.","breadcrumbs":"Design » Use of cm","id":"31","title":"Use of cm"},"32":{"body":"Orchard signatures are an instantiation of RedDSA with a cofactor of 1. TODO: Should it be possible to sign partial transactions? If we're going to merge down all the signatures into a single one, and also want this, we need to ensure there's a feasible MPC.","breadcrumbs":"Design » Signatures","id":"32","title":"Signatures"},"33":{"body":"","breadcrumbs":"Design » Circuit","id":"33","title":"Circuit"},"34":{"body":"The Orchard circuit makes use of the following gadgets from the halo2_gadgets crate: Elliptic curve : FixedPoint FixedPointBaseField FixedPointShort NonIdentityPoint Point Poseidon: Hash Sinsemilla : CommitDomain Message MessagePiece MerklePath It instantiates the instruction sets required for these gadgets with the following chips: halo2_gadgets::ecc::chip::EccChip halo2_gadgets::poseidon::Pow5Chip halo2_gadgets::sinsemilla::chip::SinsemillaChip halo2_gadgets::sinsemilla::merkle::chip::MerkleChip halo2_gadgets::utilities::UtilitiesInstructions halo2_gadgets::utilities::lookup_range_check::LookupRangeCheckConfig It also makes use of the following utility functions for standardising constraints: halo2_gadgets::utilities::{bitrange_subset, bool_check}","breadcrumbs":"Design » Circuit » Gadgets","id":"34","title":"Gadgets"},"35":{"body":"","breadcrumbs":"Design » Circuit » Commitivk","id":"35","title":"Commitivk"},"36":{"body":"SinsemillaShortCommit is used in the Commitivk function . The input to SinsemillaShortCommit is: I2LEBSPℓbaseOrchardp​​(ak)∣∣I2LEBSPℓbaseOrchardp​​(nk), where ak, nk are Pallas base field elements, and ℓbaseOrchardp​=255. Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into chunks: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=a∣∣b0​∣∣b1​=(bits 0..=249 of ak)∣∣(bits 250..=253 of ak)∣∣(bit 254 of ak)=b2​∣∣c∣∣d0​∣∣d1​=(bits 0..=4 of nk)∣∣(bits 5..=244 of nk)∣∣(bits 245..=253 of nk)∣∣(bit 254 of nk)​​ Then we recompose the chunks into message pieces: Length (bits)2501024010​Pieceab=b0​∣∣b1​∣∣b2​cd=d0​∣∣d1​​​ Each message piece is constrained by SinsemillaHash to its stated length. Additionally, ak and nk are witnessed as field elements, so we know they are canonical. However, we need additional constraints to enforce that: The chunks are the correct bit lengths (or else they could overlap in the decompositions and allow the prover to witness an arbitrary SinsemillaShortCommit message). The chunks contain the canonical decompositions of ak and nk (or else the prover could witness an input to SinsemillaShortCommit that is equivalent to ak and nk but not identical). Some of these constraints can be implemented with reusable circuit gadgets. We define a custom gate controlled by the selector qCommitivk​ to hold the remaining constraints.","breadcrumbs":"Design » Circuit » Message decomposition","id":"36","title":"Message decomposition"},"37":{"body":"Chunks a and c are directly constrained by Sinsemilla. For the remaining chunks, we use the following constraints: Degree33​Constraintshort_lookup_range_check(b0​,4)short_lookup_range_check(b2​,5)short_lookup_range_check(d0​,9)qCommitivk​⋅bool_check(b1​)=0qCommitivk​⋅bool_check(d1​)=0​​ where bool_check(x)=x⋅(1−x) and short_lookup_range_check() is a short lookup range check .","breadcrumbs":"Design » Circuit » Bit length constraints","id":"37","title":"Bit length constraints"},"38":{"body":"We have now derived or witnessed every subpiece, and range-constrained every subpiece: a (250 bits) is witnessed and constrained outside the gate; b0​ (4 bits) is witnessed and constrained outside the gate; b1​ (1 bits) is witnessed and boolean-constrained in the gate; b2​ (5 bits) is witnessed and constrained outside the gate; c (240 bits) is witnessed and constrained outside the gate; d0​ (9 bits) is witnessed and constrained outside the gate; d1​ (1 bits) is witnessed and boolean-constrained in the gate. We can now use them to reconstruct both the (chunked) message pieces, and the original field element inputs: bdaknk​=b0​+24⋅b1​+25⋅b2​=d0​+29⋅d1​=a+2250⋅b0​+2254⋅b1​=b2​+25⋅c+2245⋅d0​+2254⋅d1​​​ Degree2222​ConstraintqCommitivk​⋅(b−(b0​+b1​⋅24+b2​⋅25))=0qCommitivk​⋅(d−(d0​+d1​⋅29))=0qCommitivk​⋅(a+b0​⋅2250+b1​⋅2254−ak)=0qCommitivk​⋅(b2​+c⋅25+d0​⋅2245+d1​⋅2254−nk)=0​​","breadcrumbs":"Design » Circuit » Decomposition constraints","id":"38","title":"Decomposition constraints"},"39":{"body":"At this point, we have constrained I2LEBSPℓbaseOrchardp​​(ak) and I2LEBSPℓbaseOrchardp​​(nk) to be 255-bit values, with top bits b1​ and d1​ respectively. We have also constrained: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=ak(modqP​)=nk(modqP​)​​ where qP​ is the Pallas base field modulus. The remaining constraints will enforce that these are indeed canonically-encoded field elements, i.e. I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​, that each were appended in-order). The motivation for considering this change was to improve the lives of light client wallet developers. When a new note is received, the wallet derives its incremental witness from the state of the global tree at the point when the note's commitment is appended; this incremental state then needs to be updated with every subsequent commitment in the block in-order. Wallets can't get help from the server to create these for new notes without leaking the specific note that was received. We decided that this was too large a change from Sapling, and that it should be possible to improve the Incremental Merkle Tree implementation to work around the efficiency issues without domain-separating the tree.","breadcrumbs":"Design » Commitment tree » Considered alternatives","id":"24","title":"Considered alternatives"},"25":{"body":"The nullifier design we use for Orchard is nf=ExtractP​([(Fnk​(ρ)+ψ)modp]G+cm), where: F is a keyed circuit-efficient PRF (such as Rescue or Poseidon). ρ is unique to this output. As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. Given that an action consists of a single spend and a single output, we set ρ to be the nullifier of the spent note. ψ is sender-controlled randomness. It is not required to be unique, and in practice is derived from both ρ and a sender-selected random value rseed: ψ=KDFψ(ρ,rseed). G is a fixed independent base. ExtractP​ extracts the x-coordinate of a Pallas curve point. This gives a note structure of (addr,v,ρ,ψ,rcm). The note plaintext includes rseed in place of ψ and rcm, and omits ρ (which is a public part of the action).","breadcrumbs":"Design » Nullifiers » Nullifiers","id":"25","title":"Nullifiers"},"26":{"body":"We care about several security properties for our nullifiers: Balance: can I forge money? Note Privacy: can I gain information about notes only from the public block chain? This describes notes sent in-band. Note Privacy (OOB): can I gain information about notes sent out-of-band, only from the public block chain? In this case, we assume privacy of the channel over which the note is sent, and that the adversary does not have access to any notes sent to the same address which are then spent (so that the nullifier is on the block chain somewhere). Spend Unlinkability: given the incoming viewing key for an address, and not the full viewing key, can I (possibly the sender) detect spends of any notes sent to that address? We're giving ivk to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address. Faerie Resistance: can I perform a Faerie Gold attack (i.e. cause notes to be accepted that are unspendable)? We're giving the full viewing key to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address, and be able to derive every nullifier. We assume (and instantiate elsewhere) the following primitives: GH is a cryptographic hash into the group (such as BLAKE2s with simplified SWU), used to derive all fixed independent bases. E is an elliptic curve (such as Pallas). KDF is the note encryption key derivation function. For our chosen design, our desired security properties rely on the following assumptions: BalanceNote PrivacyNote Privacy (OOB)Spend UnlinkabilityFaerie Resistance​DLE​HashDHEKDF​Near perfect‡DDHE†​∨PRFF​DLE​​​ HashDHEKDF​ is computational Diffie-Hellman using KDF for the key derivation, with one-time ephemeral keys. This assumption is heuristically weaker than DDHE​ but stronger than DLE​. We omit ROGH​ as a security assumption because we only rely on the random oracle applied to fixed inputs defined by the protocol, i.e. to generate the fixed base G, not to attacker-specified inputs. † We additionally assume that for any input x, {Fnk​(x):nk∈E} gives a scalar in an adequate range for DDHE​. (Otherwise, F could be trivial, e.g. independent of nk.) ‡ Statistical distance <2−167.8 from perfect.","breadcrumbs":"Design » Nullifiers » Security properties","id":"26","title":"Security properties"},"27":{"body":"⚠ Caution: be skeptical of the claims in this table about what problem(s) each security property depends on. They may not be accurate and are definitely not fully rigorous. The entries in this table omit the application of ExtractP​, which is an optimization to halve the nullifier length. That optimization requires its own security analysis, but because it is a deterministic mapping, only Faerie Resistance could be affected by it. nf[nk][θ]H[nk]H+[rnf]IHash([nk][θ]H)Hash([nk]H+[rnf]I)[Fnk​(ψ)][θ]H[Fnk​(ψ)]H+[rnf]I[Fnk​(ψ)]G+[θ]H[Fnk​(ψ)]H+cm[Fnk​(ρ,ψ)]G+cm[Fnk​(ρ)]G+cm[Fnk​(ρ,ψ)]Gv​+[rnf]I[Fnk​(ρ)]Gv​+[rnf]I[(Fnk​(ρ)+ψ)modp]Gv​[Fnk​(ρ,ψ)]G+Commitrnfnf​(v,ρ)[Fnk​(ρ)]G+Commitrnfnf​(v,ρ)​Note(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,rnf,ψ,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,ψ,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)​BalanceDLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​​Note PrivacyHashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​​Note Priv OOBPerfectPerfectPerfectPerfectPerfectPerfectPerfectDDHE†​DDHE†​DDHE†​PerfectPerfectNear perfect‡PerfectPerfect​Spend UnlinkabilityDDHE​DDHE​DDHE​∨PreHash​DDHE​∨PreHash​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​​Faerie ResistanceROGH​∧DLE​ROGH​∧DLE​CollHash​∧ROGH​∧DLE​CollHash​∧ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​DLE​DLE​CollF​∧DLE​CollF​∧DLE​brokenDLE​DLE​​Reason not to useNo SU for DL-breakingNo SU for DL-breakingCollHash​ for FRCollHash​ for FRPerf. (2 var-base)Perf. (1 var+1 fix-base)Perf. (1 var+1 fix-base)NP(OOB) not perfectNP(OOB) not perfectNP(OOB) not perfectCollF​ for FRCollF​ for FRbroken for FRPerf. (2 fix-base)Perf. (2 fix-base)​​ In the above alternatives: Hash is a keyed circuit-efficient hash (such as Rescue). I is an fixed independent base, independent of G and any others returned by GH. Gv​ is a pair of fixed independent bases (independent of all others), where the specific choice of base depends on whether the note has zero value. H is a base unique to this output. For non-zero-valued notes, H=GH(ρ). As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. For zero-valued notes, H is constrained by the circuit to a fixed base independent of I and any others returned by GH.","breadcrumbs":"Design » Nullifiers » Considered alternatives","id":"27","title":"Considered alternatives"},"28":{"body":"In order to satisfy the Balance security property, we require that the circuit must be able to enforce that only one nullifier is accepted for a given note. As in Sprout and Sapling, we achieve this by ensuring that the nullifier deterministically depends only on values committed to (directly or indirectly) by the note commitment. As in Sapling, this involves arguing that: There can be only one ivk for a given addr. This is true because the circuit checks that pkd​=[ivk]gd​, and the mapping ivk↦[ivk]gd​ is an injection for any gd​. (ivk is in the base field of E, which must be smaller than its scalar field, as is the case for Pallas.) There can be only one nk for a given ivk. This is true because the circuit checks that ivk=ShortCommitrivkivk​(ak,nk) where ShortCommit is binding (see Commitments ).","breadcrumbs":"Design » Nullifiers » Rationale","id":"28","title":"Rationale"},"29":{"body":"Faerie Resistance requires that nullifiers be unique. This is primarily achieved by taking a unique value (checked for uniqueness by the public consensus rules) as an input to the nullifier. However, it is also necessary to ensure that the transformations applied to this value preserve its uniqueness. Meanwhile, to achieve Spend Unlinkability , we require that the nullifier does not reveal any information about the unique value it is derived from. The design alternatives fall into two categories in terms of how they balance these requirements: Publish a unique value ρ at note creation time, and blind that value within the nullifier computation. This is similar to the approach taken in Sprout and Sapling, which both implemented nullifiers as PRF outputs; Sprout uses the compression function from SHA-256, while Sapling uses BLAKE2s. Derive a unique base H from some unique value, publish that unique base at note creation time, and then blind the base (either additively or multiplicatively) during nullifier computation. For Spend Unlinkability , the only value unknown to the adversary is nk, and the cryptographic assumptions only involve the first term (other terms like cm or [rnf]I cannot be extracted directly from the observed nullifiers, but can be subtracted from them). We therefore ensure that the first term does not commit directly to the note (to avoid a DL-breaking adversary from immediately breaking SU ). We were considering using a design involving H with the goal of eliminating all usages of a PRF inside the circuit, for two reasons: Instantiating PRFF​ with a traditional hash function is expensive in the circuit. We didn't want to solely rely on an algebraic hash function satisfying PRFF​ to achieve Spend Unlinkability . However, those designs rely on both ROGH​ and DLE​ for Faerie Resistance , while still requiring DDHE​ for Spend Unlinkability . (There are two designs for which this is not the case, but they rely on DDHE†​ for Note Privacy (OOB) which was not acceptable). By contrast, several designs involving ρ (including the chosen design) have weaker assumptions for Faerie Resistance (only relying on DLE​), and Spend Unlinkability does not require PRFF​ to hold: they can fall back on the same DDHE​ assumption as the H designs (along with an additional assumption about the output of F which is easily satisfied).","breadcrumbs":"Design » Nullifiers » Use of ρ","id":"29","title":"Use of ρ"},"3":{"body":"","breadcrumbs":"Concepts » Concepts","id":"3","title":"Concepts"},"30":{"body":"Most of the designs include either a multiplicative blinding term [θ]H, or an additive blinding term [rnf]I, in order to achieve perfect Note Privacy (OOB) (to an adversary who does not know the note). The chosen design is effectively using [ψ]G for this purpose; a DL-breaking adversary only learns Fnk​(ρ)+ψ(modp). This reduces Note Privacy (OOB) from perfect to statistical, but given that ψ is from a distribution statistically close to uniform on [0,q), this is statistically close to better than 2−128. The benefit is that it does not require an additional scalar multiplication, making it more efficient inside the circuit. ψ's derivation has two motivations: Deriving from a random value rseed enables multiple derived values to be conveyed to the recipient within an action (such as the ephemeral secret esk, per ZIP 212 ), while keeping the note plaintext short. Mixing ρ into the derivation ensures that the sender can't repeat ψ across two notes, which could have enabled spend linkability attacks in some designs. The note that is committed to, and which the circuit takes as input, only includes ψ (i.e. the circuit does not check the derivation from rseed). However, an adversarial sender is still constrained by this derivation, because the recipient recomputes ψ during note decryption. If an action were created using an arbitrary ψ (for which the adversary did not have a corresponding rseed), the recipient would derive a note commitment that did not match the action's commitment field, and reject it (as in Sapling).","breadcrumbs":"Design » Nullifiers » Use of ψ","id":"30","title":"Use of ψ"},"31":{"body":"The nullifier commits to the note value via cm for two reasons: It domain-separates nullifiers for zero-valued notes from other notes. This is necessary because we do not require zero-valued notes to exist in the commitment tree. Designs that bind the nullifier to Fnk​(ρ) require CollF​ to achieve Faerie Resistance (and similarly where Hash is applied to a value derived from H). Adding cm to the nullifier avoids this assumption: all of the bases used to derive cm are fixed and independent of G, and so the nullifier can be viewed as a Pedersen hash where the input includes ρ directly. The Commitnf variants were considered to avoid directly depending on cm (which in its native type is a base field element, not a group element). We decided instead to follow Sapling by defining an intermediate representation of cm as a group element, that is only used in nullifier computation. The circuit already needs to compute cm, so this improves performance by removing an additional commitment calculation from the circuit. We also considered variants that used a choice of fixed bases Gv​ to provide domain separation for zero-valued notes. The most performant design (similar to the chosen design) does not achieve Faerie Resistance for an adversary that knows the recipient's full viewing key (ψ could be brute-forced to cancel out Fnk​(ρ), causing a collision), and the other variants require assuming CollF​ as mentioned above.","breadcrumbs":"Design » Nullifiers » Use of cm","id":"31","title":"Use of cm"},"32":{"body":"Orchard signatures are an instantiation of RedDSA with a cofactor of 1. TODO: Should it be possible to sign partial transactions? If we're going to merge down all the signatures into a single one, and also want this, we need to ensure there's a feasible MPC.","breadcrumbs":"Design » Signatures » Signatures","id":"32","title":"Signatures"},"33":{"body":"","breadcrumbs":"Design » Circuit » Circuit","id":"33","title":"Circuit"},"34":{"body":"The Orchard circuit makes use of the following gadgets from the halo2_gadgets crate: Elliptic curve : FixedPoint FixedPointBaseField FixedPointShort NonIdentityPoint Point Poseidon: Hash Sinsemilla : CommitDomain Message MessagePiece MerklePath It instantiates the instruction sets required for these gadgets with the following chips: halo2_gadgets::ecc::chip::EccChip halo2_gadgets::poseidon::Pow5Chip halo2_gadgets::sinsemilla::chip::SinsemillaChip halo2_gadgets::sinsemilla::merkle::chip::MerkleChip halo2_gadgets::utilities::UtilitiesInstructions halo2_gadgets::utilities::lookup_range_check::LookupRangeCheckConfig It also makes use of the following utility functions for standardising constraints: halo2_gadgets::utilities::{bitrange_subset, bool_check}","breadcrumbs":"Design » Circuit » Gadgets » Gadgets","id":"34","title":"Gadgets"},"35":{"body":"","breadcrumbs":"Design » Circuit » CommitIvk » Commitivk","id":"35","title":"Commitivk"},"36":{"body":"SinsemillaShortCommit is used in the Commitivk function . The input to SinsemillaShortCommit is: I2LEBSPℓbaseOrchardp​​(ak)∣∣I2LEBSPℓbaseOrchardp​​(nk), where ak, nk are Pallas base field elements, and ℓbaseOrchardp​=255. Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into chunks: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=a∣∣b0​∣∣b1​=(bits 0..=249 of ak)∣∣(bits 250..=253 of ak)∣∣(bit 254 of ak)=b2​∣∣c∣∣d0​∣∣d1​=(bits 0..=4 of nk)∣∣(bits 5..=244 of nk)∣∣(bits 245..=253 of nk)∣∣(bit 254 of nk)​​ Then we recompose the chunks into message pieces: Length (bits)2501024010​Pieceab=b0​∣∣b1​∣∣b2​cd=d0​∣∣d1​​​ Each message piece is constrained by SinsemillaHash to its stated length. Additionally, ak and nk are witnessed as field elements, so we know they are canonical. However, we need additional constraints to enforce that: The chunks are the correct bit lengths (or else they could overlap in the decompositions and allow the prover to witness an arbitrary SinsemillaShortCommit message). The chunks contain the canonical decompositions of ak and nk (or else the prover could witness an input to SinsemillaShortCommit that is equivalent to ak and nk but not identical). Some of these constraints can be implemented with reusable circuit gadgets. We define a custom gate controlled by the selector qCommitivk​ to hold the remaining constraints.","breadcrumbs":"Design » Circuit » CommitIvk » Message decomposition","id":"36","title":"Message decomposition"},"37":{"body":"Chunks a and c are directly constrained by Sinsemilla. For the remaining chunks, we use the following constraints: Degree33​Constraintshort_lookup_range_check(b0​,4)short_lookup_range_check(b2​,5)short_lookup_range_check(d0​,9)qCommitivk​⋅bool_check(b1​)=0qCommitivk​⋅bool_check(d1​)=0​​ where bool_check(x)=x⋅(1−x) and short_lookup_range_check() is a short lookup range check .","breadcrumbs":"Design » Circuit » CommitIvk » Bit length constraints","id":"37","title":"Bit length constraints"},"38":{"body":"We have now derived or witnessed every subpiece, and range-constrained every subpiece: a (250 bits) is witnessed and constrained outside the gate; b0​ (4 bits) is witnessed and constrained outside the gate; b1​ (1 bits) is witnessed and boolean-constrained in the gate; b2​ (5 bits) is witnessed and constrained outside the gate; c (240 bits) is witnessed and constrained outside the gate; d0​ (9 bits) is witnessed and constrained outside the gate; d1​ (1 bits) is witnessed and boolean-constrained in the gate. We can now use them to reconstruct both the (chunked) message pieces, and the original field element inputs: bdaknk​=b0​+24⋅b1​+25⋅b2​=d0​+29⋅d1​=a+2250⋅b0​+2254⋅b1​=b2​+25⋅c+2245⋅d0​+2254⋅d1​​​ Degree2222​ConstraintqCommitivk​⋅(b−(b0​+b1​⋅24+b2​⋅25))=0qCommitivk​⋅(d−(d0​+d1​⋅29))=0qCommitivk​⋅(a+b0​⋅2250+b1​⋅2254−ak)=0qCommitivk​⋅(b2​+c⋅25+d0​⋅2245+d1​⋅2254−nk)=0​​","breadcrumbs":"Design » Circuit » CommitIvk » Decomposition constraints","id":"38","title":"Decomposition constraints"},"39":{"body":"At this point, we have constrained I2LEBSPℓbaseOrchardp​​(ak) and I2LEBSPℓbaseOrchardp​​(nk) to be 255-bit values, with top bits b1​ and d1​ respectively. We have also constrained: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=ak(modqP​)=nk(modqP​)​​ where qP​ is the Pallas base field modulus. The remaining constraints will enforce that these are indeed canonically-encoded field elements, i.e. I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​, that each were appended in-order). The motivation for considering this change was to improve the lives of light client wallet developers. When a new note is received, the wallet derives its incremental witness from the state of the global tree at the point when the note's commitment is appended; this incremental state then needs to be updated with every subsequent commitment in the block in-order. Wallets can't get help from the server to create these for new notes without leaking the specific note that was received. We decided that this was too large a change from Sapling, and that it should be possible to improve the Incremental Merkle Tree implementation to work around the efficiency issues without domain-separating the tree.","breadcrumbs":"Design » Considered alternatives","id":"24","title":"Considered alternatives"},"25":{"body":"The nullifier design we use for Orchard is nf=ExtractP​([(Fnk​(ρ)+ψ)modp]G+cm), where: F is a keyed circuit-efficient PRF (such as Rescue or Poseidon). ρ is unique to this output. As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. Given that an action consists of a single spend and a single output, we set ρ to be the nullifier of the spent note. ψ is sender-controlled randomness. It is not required to be unique, and in practice is derived from both ρ and a sender-selected random value rseed: ψ=KDFψ(ρ,rseed). G is a fixed independent base. ExtractP​ extracts the x-coordinate of a Pallas curve point. This gives a note structure of (addr,v,ρ,ψ,rcm). The note plaintext includes rseed in place of ψ and rcm, and omits ρ (which is a public part of the action).","breadcrumbs":"Design » Nullifiers","id":"25","title":"Nullifiers"},"26":{"body":"We care about several security properties for our nullifiers: Balance: can I forge money? Note Privacy: can I gain information about notes only from the public block chain? This describes notes sent in-band. Note Privacy (OOB): can I gain information about notes sent out-of-band, only from the public block chain? In this case, we assume privacy of the channel over which the note is sent, and that the adversary does not have access to any notes sent to the same address which are then spent (so that the nullifier is on the block chain somewhere). Spend Unlinkability: given the incoming viewing key for an address, and not the full viewing key, can I (possibly the sender) detect spends of any notes sent to that address? We're giving ivk to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address. Faerie Resistance: can I perform a Faerie Gold attack (i.e. cause notes to be accepted that are unspendable)? We're giving the full viewing key to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address, and be able to derive every nullifier. We assume (and instantiate elsewhere) the following primitives: GH is a cryptographic hash into the group (such as BLAKE2s with simplified SWU), used to derive all fixed independent bases. E is an elliptic curve (such as Pallas). KDF is the note encryption key derivation function. For our chosen design, our desired security properties rely on the following assumptions: BalanceNote PrivacyNote Privacy (OOB)Spend UnlinkabilityFaerie Resistance​DLE​HashDHEKDF​Near perfect‡DDHE†​∨PRFF​DLE​​​ HashDHEKDF​ is computational Diffie-Hellman using KDF for the key derivation, with one-time ephemeral keys. This assumption is heuristically weaker than DDHE​ but stronger than DLE​. We omit ROGH​ as a security assumption because we only rely on the random oracle applied to fixed inputs defined by the protocol, i.e. to generate the fixed base G, not to attacker-specified inputs. † We additionally assume that for any input x, {Fnk​(x):nk∈E} gives a scalar in an adequate range for DDHE​. (Otherwise, F could be trivial, e.g. independent of nk.) ‡ Statistical distance <2−167.8 from perfect.","breadcrumbs":"Design » Security properties","id":"26","title":"Security properties"},"27":{"body":"⚠ Caution: be skeptical of the claims in this table about what problem(s) each security property depends on. They may not be accurate and are definitely not fully rigorous. The entries in this table omit the application of ExtractP​, which is an optimization to halve the nullifier length. That optimization requires its own security analysis, but because it is a deterministic mapping, only Faerie Resistance could be affected by it. nf[nk][θ]H[nk]H+[rnf]IHash([nk][θ]H)Hash([nk]H+[rnf]I)[Fnk​(ψ)][θ]H[Fnk​(ψ)]H+[rnf]I[Fnk​(ψ)]G+[θ]H[Fnk​(ψ)]H+cm[Fnk​(ρ,ψ)]G+cm[Fnk​(ρ)]G+cm[Fnk​(ρ,ψ)]Gv​+[rnf]I[Fnk​(ρ)]Gv​+[rnf]I[(Fnk​(ρ)+ψ)modp]Gv​[Fnk​(ρ,ψ)]G+Commitrnfnf​(v,ρ)[Fnk​(ρ)]G+Commitrnfnf​(v,ρ)​Note(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,rnf,ψ,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,ψ,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)​BalanceDLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​​Note PrivacyHashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​​Note Priv OOBPerfectPerfectPerfectPerfectPerfectPerfectPerfectDDHE†​DDHE†​DDHE†​PerfectPerfectNear perfect‡PerfectPerfect​Spend UnlinkabilityDDHE​DDHE​DDHE​∨PreHash​DDHE​∨PreHash​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​​Faerie ResistanceROGH​∧DLE​ROGH​∧DLE​CollHash​∧ROGH​∧DLE​CollHash​∧ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​DLE​DLE​CollF​∧DLE​CollF​∧DLE​brokenDLE​DLE​​Reason not to useNo SU for DL-breakingNo SU for DL-breakingCollHash​ for FRCollHash​ for FRPerf. (2 var-base)Perf. (1 var+1 fix-base)Perf. (1 var+1 fix-base)NP(OOB) not perfectNP(OOB) not perfectNP(OOB) not perfectCollF​ for FRCollF​ for FRbroken for FRPerf. (2 fix-base)Perf. (2 fix-base)​​ In the above alternatives: Hash is a keyed circuit-efficient hash (such as Rescue). I is an fixed independent base, independent of G and any others returned by GH. Gv​ is a pair of fixed independent bases (independent of all others), where the specific choice of base depends on whether the note has zero value. H is a base unique to this output. For non-zero-valued notes, H=GH(ρ). As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. For zero-valued notes, H is constrained by the circuit to a fixed base independent of I and any others returned by GH.","breadcrumbs":"Design » Considered alternatives","id":"27","title":"Considered alternatives"},"28":{"body":"In order to satisfy the Balance security property, we require that the circuit must be able to enforce that only one nullifier is accepted for a given note. As in Sprout and Sapling, we achieve this by ensuring that the nullifier deterministically depends only on values committed to (directly or indirectly) by the note commitment. As in Sapling, this involves arguing that: There can be only one ivk for a given addr. This is true because the circuit checks that pkd​=[ivk]gd​, and the mapping ivk↦[ivk]gd​ is an injection for any gd​. (ivk is in the base field of E, which must be smaller than its scalar field, as is the case for Pallas.) There can be only one nk for a given ivk. This is true because the circuit checks that ivk=ShortCommitrivkivk​(ak,nk) where ShortCommit is binding (see Commitments ).","breadcrumbs":"Design » Rationale","id":"28","title":"Rationale"},"29":{"body":"Faerie Resistance requires that nullifiers be unique. This is primarily achieved by taking a unique value (checked for uniqueness by the public consensus rules) as an input to the nullifier. However, it is also necessary to ensure that the transformations applied to this value preserve its uniqueness. Meanwhile, to achieve Spend Unlinkability , we require that the nullifier does not reveal any information about the unique value it is derived from. The design alternatives fall into two categories in terms of how they balance these requirements: Publish a unique value ρ at note creation time, and blind that value within the nullifier computation. This is similar to the approach taken in Sprout and Sapling, which both implemented nullifiers as PRF outputs; Sprout uses the compression function from SHA-256, while Sapling uses BLAKE2s. Derive a unique base H from some unique value, publish that unique base at note creation time, and then blind the base (either additively or multiplicatively) during nullifier computation. For Spend Unlinkability , the only value unknown to the adversary is nk, and the cryptographic assumptions only involve the first term (other terms like cm or [rnf]I cannot be extracted directly from the observed nullifiers, but can be subtracted from them). We therefore ensure that the first term does not commit directly to the note (to avoid a DL-breaking adversary from immediately breaking SU ). We were considering using a design involving H with the goal of eliminating all usages of a PRF inside the circuit, for two reasons: Instantiating PRFF​ with a traditional hash function is expensive in the circuit. We didn't want to solely rely on an algebraic hash function satisfying PRFF​ to achieve Spend Unlinkability . However, those designs rely on both ROGH​ and DLE​ for Faerie Resistance , while still requiring DDHE​ for Spend Unlinkability . (There are two designs for which this is not the case, but they rely on DDHE†​ for Note Privacy (OOB) which was not acceptable). By contrast, several designs involving ρ (including the chosen design) have weaker assumptions for Faerie Resistance (only relying on DLE​), and Spend Unlinkability does not require PRFF​ to hold: they can fall back on the same DDHE​ assumption as the H designs (along with an additional assumption about the output of F which is easily satisfied).","breadcrumbs":"Design » Use of ρ","id":"29","title":"Use of ρ"},"3":{"body":"","breadcrumbs":"Concepts","id":"3","title":"Concepts"},"30":{"body":"Most of the designs include either a multiplicative blinding term [θ]H, or an additive blinding term [rnf]I, in order to achieve perfect Note Privacy (OOB) (to an adversary who does not know the note). The chosen design is effectively using [ψ]G for this purpose; a DL-breaking adversary only learns Fnk​(ρ)+ψ(modp). This reduces Note Privacy (OOB) from perfect to statistical, but given that ψ is from a distribution statistically close to uniform on [0,q), this is statistically close to better than 2−128. The benefit is that it does not require an additional scalar multiplication, making it more efficient inside the circuit. ψ's derivation has two motivations: Deriving from a random value rseed enables multiple derived values to be conveyed to the recipient within an action (such as the ephemeral secret esk, per ZIP 212 ), while keeping the note plaintext short. Mixing ρ into the derivation ensures that the sender can't repeat ψ across two notes, which could have enabled spend linkability attacks in some designs. The note that is committed to, and which the circuit takes as input, only includes ψ (i.e. the circuit does not check the derivation from rseed). However, an adversarial sender is still constrained by this derivation, because the recipient recomputes ψ during note decryption. If an action were created using an arbitrary ψ (for which the adversary did not have a corresponding rseed), the recipient would derive a note commitment that did not match the action's commitment field, and reject it (as in Sapling).","breadcrumbs":"Design » Use of ψ","id":"30","title":"Use of ψ"},"31":{"body":"The nullifier commits to the note value via cm for two reasons: It domain-separates nullifiers for zero-valued notes from other notes. This is necessary because we do not require zero-valued notes to exist in the commitment tree. Designs that bind the nullifier to Fnk​(ρ) require CollF​ to achieve Faerie Resistance (and similarly where Hash is applied to a value derived from H). Adding cm to the nullifier avoids this assumption: all of the bases used to derive cm are fixed and independent of G, and so the nullifier can be viewed as a Pedersen hash where the input includes ρ directly. The Commitnf variants were considered to avoid directly depending on cm (which in its native type is a base field element, not a group element). We decided instead to follow Sapling by defining an intermediate representation of cm as a group element, that is only used in nullifier computation. The circuit already needs to compute cm, so this improves performance by removing We also considered variants that used a choice of fixed bases Gv​ to provide domain separation for zero-valued notes. The most performant design (similar to the chosen design) does not achieve Faerie Resistance for an adversary that knows the recipient's full viewing key (ψ could be brute-forced to cancel out Fnk​(ρ), causing a collision), and the other variants require assuming CollF​ as mentioned above.","breadcrumbs":"Design » Use of cm","id":"31","title":"Use of cm"},"32":{"body":"Orchard signatures are an instantiation of RedDSA with a cofactor of 1. TODO: Should it be possible to sign partial transactions? If we're going to merge down all the signatures into a single one, and also want this, we need to ensure there's a feasible MPC.","breadcrumbs":"Design » Signatures","id":"32","title":"Signatures"},"33":{"body":"","breadcrumbs":"Design » Circuit","id":"33","title":"Circuit"},"34":{"body":"The Orchard circuit makes use of the following gadgets from the halo2_gadgets crate: Elliptic curve : FixedPoint FixedPointBaseField FixedPointShort NonIdentityPoint Point Poseidon: Hash Sinsemilla : CommitDomain Message MessagePiece MerklePath It instantiates the instruction sets required for these gadgets with the following chips: halo2_gadgets::ecc::chip::EccChip halo2_gadgets::poseidon::Pow5Chip halo2_gadgets::sinsemilla::chip::SinsemillaChip halo2_gadgets::sinsemilla::merkle::chip::MerkleChip halo2_gadgets::utilities::UtilitiesInstructions halo2_gadgets::utilities::lookup_range_check::LookupRangeCheckConfig It also makes use of the following utility functions for standardising constraints: halo2_gadgets::utilities::{bitrange_subset, bool_check}","breadcrumbs":"Design » Circuit » Gadgets","id":"34","title":"Gadgets"},"35":{"body":"","breadcrumbs":"Design » Circuit » Commitivk","id":"35","title":"Commitivk"},"36":{"body":"SinsemillaShortCommit is used in the Commitivk function . The input to SinsemillaShortCommit is: I2LEBSPℓbaseOrchardp​​(ak)∣∣I2LEBSPℓbaseOrchardp​​(nk), where ak, nk are Pallas base field elements, and ℓbaseOrchardp​=255. Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into chunks: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=a∣∣b0​∣∣b1​=(bits 0..=249 of ak)∣∣(bits 250..=253 of ak)∣∣(bit 254 of ak)=b2​∣∣c∣∣d0​∣∣d1​=(bits 0..=4 of nk)∣∣(bits 5..=244 of nk)∣∣(bits 245..=253 of nk)∣∣(bit 254 of nk)​​ Then we recompose the chunks into message pieces: Length (bits)2501024010​Pieceab=b0​∣∣b1​∣∣b2​cd=d0​∣∣d1​​​ Each message piece is constrained by SinsemillaHash to its stated length. Additionally, ak and nk are witnessed as field elements, so we know they are canonical. However, we need additional constraints to enforce that: The chunks are the correct bit lengths (or else they could overlap in the decompositions and allow the prover to witness an arbitrary SinsemillaShortCommit message). The chunks contain the canonical decompositions of ak and nk (or else the prover could witness an input to SinsemillaShortCommit that is equivalent to ak and nk but not identical). Some of these constraints can be implemented with reusable circuit gadgets. We define a custom gate controlled by the selector qCommitivk​ to hold the remaining constraints.","breadcrumbs":"Design » Circuit » Message decomposition","id":"36","title":"Message decomposition"},"37":{"body":"Chunks a and c are directly constrained by Sinsemilla. For the remaining chunks, we use the following constraints: Degree33​Constraintshort_lookup_range_check(b0​,4)short_lookup_range_check(b2​,5)short_lookup_range_check(d0​,9)qCommitivk​⋅bool_check(b1​)=0qCommitivk​⋅bool_check(d1​)=0​​ where bool_check(x)=x⋅(1−x) and short_lookup_range_check() is a short lookup range check .","breadcrumbs":"Design » Circuit » Bit length constraints","id":"37","title":"Bit length constraints"},"38":{"body":"We have now derived or witnessed every subpiece, and range-constrained every subpiece: a (250 bits) is witnessed and constrained outside the gate; b0​ (4 bits) is witnessed and constrained outside the gate; b1​ (1 bits) is witnessed and boolean-constrained in the gate; b2​ (5 bits) is witnessed and constrained outside the gate; c (240 bits) is witnessed and constrained outside the gate; d0​ (9 bits) is witnessed and constrained outside the gate; d1​ (1 bits) is witnessed and boolean-constrained in the gate. We can now use them to reconstruct both the (chunked) message pieces, and the original field element inputs: bdaknk​=b0​+24⋅b1​+25⋅b2​=d0​+29⋅d1​=a+2250⋅b0​+2254⋅b1​=b2​+25⋅c+2245⋅d0​+2254⋅d1​​​ Degree2222​ConstraintqCommitivk​⋅(b−(b0​+b1​⋅24+b2​⋅25))=0qCommitivk​⋅(d−(d0​+d1​⋅29))=0qCommitivk​⋅(a+b0​⋅2250+b1​⋅2254−ak)=0qCommitivk​⋅(b2​+c⋅25+d0​⋅2245+d1​⋅2254−nk)=0​​","breadcrumbs":"Design » Circuit » Decomposition constraints","id":"38","title":"Decomposition constraints"},"39":{"body":"At this point, we have constrained I2LEBSPℓbaseOrchardp​​(ak) and I2LEBSPℓbaseOrchardp​​(nk) to be 255-bit values, with top bits b1​ and d1​ respectively. We have also constrained: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=ak(modqP​)=nk(modqP​)​​ where qP​ is the Pallas base field modulus. The remaining constraints will enforce that these are indeed canonically-encoded field elements, i.e. I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​, that each were appended in-order). The motivation for considering this change was to improve the lives of light client wallet developers. When a new note is received, the wallet derives its incremental witness from the state of the global tree at the point when the note's commitment is appended; this incremental state then needs to be updated with every subsequent commitment in the block in-order. Wallets can't get help from the server to create these for new notes without leaking the specific note that was received. We decided that this was too large a change from Sapling, and that it should be possible to improve the Incremental Merkle Tree implementation to work around the efficiency issues without domain-separating the tree.","breadcrumbs":"Design » Commitment tree » Considered alternatives","id":"24","title":"Considered alternatives"},"25":{"body":"The nullifier design we use for Orchard is nf=ExtractP​([(Fnk​(ρ)+ψ)modp]G+cm), where: F is a keyed circuit-efficient PRF (such as Rescue or Poseidon). ρ is unique to this output. As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. Given that an action consists of a single spend and a single output, we set ρ to be the nullifier of the spent note. ψ is sender-controlled randomness. It is not required to be unique, and in practice is derived from both ρ and a sender-selected random value rseed: ψ=KDFψ(ρ,rseed). G is a fixed independent base. ExtractP​ extracts the x-coordinate of a Pallas curve point. This gives a note structure of (addr,v,ρ,ψ,rcm). The note plaintext includes rseed in place of ψ and rcm, and omits ρ (which is a public part of the action).","breadcrumbs":"Design » Nullifiers » Nullifiers","id":"25","title":"Nullifiers"},"26":{"body":"We care about several security properties for our nullifiers: Balance: can I forge money? Note Privacy: can I gain information about notes only from the public block chain? This describes notes sent in-band. Note Privacy (OOB): can I gain information about notes sent out-of-band, only from the public block chain? In this case, we assume privacy of the channel over which the note is sent, and that the adversary does not have access to any notes sent to the same address which are then spent (so that the nullifier is on the block chain somewhere). Spend Unlinkability: given the incoming viewing key for an address, and not the full viewing key, can I (possibly the sender) detect spends of any notes sent to that address? We're giving ivk to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address. Faerie Resistance: can I perform a Faerie Gold attack (i.e. cause notes to be accepted that are unspendable)? We're giving the full viewing key to the attacker and allowing it to be the sender in order to make this property as strong as possible: they will have all the notes sent to that address, and be able to derive every nullifier. We assume (and instantiate elsewhere) the following primitives: GH is a cryptographic hash into the group (such as BLAKE2s with simplified SWU), used to derive all fixed independent bases. E is an elliptic curve (such as Pallas). KDF is the note encryption key derivation function. For our chosen design, our desired security properties rely on the following assumptions: BalanceNote PrivacyNote Privacy (OOB)Spend UnlinkabilityFaerie Resistance​DLE​HashDHEKDF​Near perfect‡DDHE†​∨PRFF​DLE​​​ HashDHEKDF​ is computational Diffie-Hellman using KDF for the key derivation, with one-time ephemeral keys. This assumption is heuristically weaker than DDHE​ but stronger than DLE​. We omit ROGH​ as a security assumption because we only rely on the random oracle applied to fixed inputs defined by the protocol, i.e. to generate the fixed base G, not to attacker-specified inputs. † We additionally assume that for any input x, {Fnk​(x):nk∈E} gives a scalar in an adequate range for DDHE​. (Otherwise, F could be trivial, e.g. independent of nk.) ‡ Statistical distance <2−167.8 from perfect.","breadcrumbs":"Design » Nullifiers » Security properties","id":"26","title":"Security properties"},"27":{"body":"⚠ Caution: be skeptical of the claims in this table about what problem(s) each security property depends on. They may not be accurate and are definitely not fully rigorous. The entries in this table omit the application of ExtractP​, which is an optimization to halve the nullifier length. That optimization requires its own security analysis, but because it is a deterministic mapping, only Faerie Resistance could be affected by it. nf[nk][θ]H[nk]H+[rnf]IHash([nk][θ]H)Hash([nk]H+[rnf]I)[Fnk​(ψ)][θ]H[Fnk​(ψ)]H+[rnf]I[Fnk​(ψ)]G+[θ]H[Fnk​(ψ)]H+cm[Fnk​(ρ,ψ)]G+cm[Fnk​(ρ)]G+cm[Fnk​(ρ,ψ)]Gv​+[rnf]I[Fnk​(ρ)]Gv​+[rnf]I[(Fnk​(ρ)+ψ)modp]Gv​[Fnk​(ρ,ψ)]G+Commitrnfnf​(v,ρ)[Fnk​(ρ)]G+Commitrnfnf​(v,ρ)​Note(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,rcm)(addr,v,H,rnf,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,rnf,ψ,rcm)(addr,v,H,θ,ψ,rcm)(addr,v,H,ψ,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)(addr,v,ρ,ψ,rcm)(addr,v,ρ,rnf,ψ,rcm)(addr,v,ρ,rnf,rcm)​BalanceDLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​DLE​​Note PrivacyHashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​HashDHEKDF​​Note Priv OOBPerfectPerfectPerfectPerfectPerfectPerfectPerfectDDHE†​DDHE†​DDHE†​PerfectPerfectNear perfect‡PerfectPerfect​Spend UnlinkabilityDDHE​DDHE​DDHE​∨PreHash​DDHE​∨PreHash​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​DDHE†​∨PRFF​​Faerie ResistanceROGH​∧DLE​ROGH​∧DLE​CollHash​∧ROGH​∧DLE​CollHash​∧ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​ROGH​∧DLE​DLE​DLE​CollF​∧DLE​CollF​∧DLE​brokenDLE​DLE​​Reason not to useNo SU for DL-breakingNo SU for DL-breakingCollHash​ for FRCollHash​ for FRPerf. (2 var-base)Perf. (1 var+1 fix-base)Perf. (1 var+1 fix-base)NP(OOB) not perfectNP(OOB) not perfectNP(OOB) not perfectCollF​ for FRCollF​ for FRbroken for FRPerf. (2 fix-base)Perf. (2 fix-base)​​ In the above alternatives: Hash is a keyed circuit-efficient hash (such as Rescue). I is an fixed independent base, independent of G and any others returned by GH. Gv​ is a pair of fixed independent bases (independent of all others), where the specific choice of base depends on whether the note has zero value. H is a base unique to this output. For non-zero-valued notes, H=GH(ρ). As with hSig​ in Sprout, ρ includes the nullifiers of any Orchard notes being spent in the same action. For zero-valued notes, H is constrained by the circuit to a fixed base independent of I and any others returned by GH.","breadcrumbs":"Design » Nullifiers » Considered alternatives","id":"27","title":"Considered alternatives"},"28":{"body":"In order to satisfy the Balance security property, we require that the circuit must be able to enforce that only one nullifier is accepted for a given note. As in Sprout and Sapling, we achieve this by ensuring that the nullifier deterministically depends only on values committed to (directly or indirectly) by the note commitment. As in Sapling, this involves arguing that: There can be only one ivk for a given addr. This is true because the circuit checks that pkd​=[ivk]gd​, and the mapping ivk↦[ivk]gd​ is an injection for any gd​. (ivk is in the base field of E, which must be smaller than its scalar field, as is the case for Pallas.) There can be only one nk for a given ivk. This is true because the circuit checks that ivk=ShortCommitrivkivk​(ak,nk) where ShortCommit is binding (see Commitments ).","breadcrumbs":"Design » Nullifiers » Rationale","id":"28","title":"Rationale"},"29":{"body":"Faerie Resistance requires that nullifiers be unique. This is primarily achieved by taking a unique value (checked for uniqueness by the public consensus rules) as an input to the nullifier. However, it is also necessary to ensure that the transformations applied to this value preserve its uniqueness. Meanwhile, to achieve Spend Unlinkability , we require that the nullifier does not reveal any information about the unique value it is derived from. The design alternatives fall into two categories in terms of how they balance these requirements: Publish a unique value ρ at note creation time, and blind that value within the nullifier computation. This is similar to the approach taken in Sprout and Sapling, which both implemented nullifiers as PRF outputs; Sprout uses the compression function from SHA-256, while Sapling uses BLAKE2s. Derive a unique base H from some unique value, publish that unique base at note creation time, and then blind the base (either additively or multiplicatively) during nullifier computation. For Spend Unlinkability , the only value unknown to the adversary is nk, and the cryptographic assumptions only involve the first term (other terms like cm or [rnf]I cannot be extracted directly from the observed nullifiers, but can be subtracted from them). We therefore ensure that the first term does not commit directly to the note (to avoid a DL-breaking adversary from immediately breaking SU ). We were considering using a design involving H with the goal of eliminating all usages of a PRF inside the circuit, for two reasons: Instantiating PRFF​ with a traditional hash function is expensive in the circuit. We didn't want to solely rely on an algebraic hash function satisfying PRFF​ to achieve Spend Unlinkability . However, those designs rely on both ROGH​ and DLE​ for Faerie Resistance , while still requiring DDHE​ for Spend Unlinkability . (There are two designs for which this is not the case, but they rely on DDHE†​ for Note Privacy (OOB) which was not acceptable). By contrast, several designs involving ρ (including the chosen design) have weaker assumptions for Faerie Resistance (only relying on DLE​), and Spend Unlinkability does not require PRFF​ to hold: they can fall back on the same DDHE​ assumption as the H designs (along with an additional assumption about the output of F which is easily satisfied).","breadcrumbs":"Design » Nullifiers » Use of ρ","id":"29","title":"Use of ρ"},"3":{"body":"","breadcrumbs":"Concepts » Concepts","id":"3","title":"Concepts"},"30":{"body":"Most of the designs include either a multiplicative blinding term [θ]H, or an additive blinding term [rnf]I, in order to achieve perfect Note Privacy (OOB) (to an adversary who does not know the note). The chosen design is effectively using [ψ]G for this purpose; a DL-breaking adversary only learns Fnk​(ρ)+ψ(modp). This reduces Note Privacy (OOB) from perfect to statistical, but given that ψ is from a distribution statistically close to uniform on [0,q), this is statistically close to better than 2−128. The benefit is that it does not require an additional scalar multiplication, making it more efficient inside the circuit. ψ's derivation has two motivations: Deriving from a random value rseed enables multiple derived values to be conveyed to the recipient within an action (such as the ephemeral secret esk, per ZIP 212 ), while keeping the note plaintext short. Mixing ρ into the derivation ensures that the sender can't repeat ψ across two notes, which could have enabled spend linkability attacks in some designs. The note that is committed to, and which the circuit takes as input, only includes ψ (i.e. the circuit does not check the derivation from rseed). However, an adversarial sender is still constrained by this derivation, because the recipient recomputes ψ during note decryption. If an action were created using an arbitrary ψ (for which the adversary did not have a corresponding rseed), the recipient would derive a note commitment that did not match the action's commitment field, and reject it (as in Sapling).","breadcrumbs":"Design » Nullifiers » Use of ψ","id":"30","title":"Use of ψ"},"31":{"body":"The nullifier commits to the note value via cm for two reasons: It domain-separates nullifiers for zero-valued notes from other notes. This is necessary because we do not require zero-valued notes to exist in the commitment tree. Designs that bind the nullifier to Fnk​(ρ) require CollF​ to achieve Faerie Resistance (and similarly where Hash is applied to a value derived from H). Adding cm to the nullifier avoids this assumption: all of the bases used to derive cm are fixed and independent of G, and so the nullifier can be viewed as a Pedersen hash where the input includes ρ directly. The Commitnf variants were considered to avoid directly depending on cm (which in its native type is a base field element, not a group element). We decided instead to follow Sapling by defining an intermediate representation of cm as a group element, that is only used in nullifier computation. The circuit already needs to compute cm, so this improves performance by removing an additional commitment calculation from the circuit. We also considered variants that used a choice of fixed bases Gv​ to provide domain separation for zero-valued notes. The most performant design (similar to the chosen design) does not achieve Faerie Resistance for an adversary that knows the recipient's full viewing key (ψ could be brute-forced to cancel out Fnk​(ρ), causing a collision), and the other variants require assuming CollF​ as mentioned above.","breadcrumbs":"Design » Nullifiers » Use of cm","id":"31","title":"Use of cm"},"32":{"body":"Orchard signatures are an instantiation of RedDSA with a cofactor of 1. TODO: Should it be possible to sign partial transactions? If we're going to merge down all the signatures into a single one, and also want this, we need to ensure there's a feasible MPC.","breadcrumbs":"Design » Signatures » Signatures","id":"32","title":"Signatures"},"33":{"body":"","breadcrumbs":"Design » Circuit » Circuit","id":"33","title":"Circuit"},"34":{"body":"The Orchard circuit makes use of the following gadgets from the halo2_gadgets crate: Elliptic curve : FixedPoint FixedPointBaseField FixedPointShort NonIdentityPoint Point Poseidon: Hash Sinsemilla : CommitDomain Message MessagePiece MerklePath It instantiates the instruction sets required for these gadgets with the following chips: halo2_gadgets::ecc::chip::EccChip halo2_gadgets::poseidon::Pow5Chip halo2_gadgets::sinsemilla::chip::SinsemillaChip halo2_gadgets::sinsemilla::merkle::chip::MerkleChip halo2_gadgets::utilities::UtilitiesInstructions halo2_gadgets::utilities::lookup_range_check::LookupRangeCheckConfig It also makes use of the following utility functions for standardising constraints: halo2_gadgets::utilities::{bitrange_subset, bool_check}","breadcrumbs":"Design » Circuit » Gadgets » Gadgets","id":"34","title":"Gadgets"},"35":{"body":"","breadcrumbs":"Design » Circuit » CommitIvk » Commitivk","id":"35","title":"Commitivk"},"36":{"body":"SinsemillaShortCommit is used in the Commitivk function . The input to SinsemillaShortCommit is: I2LEBSPℓbaseOrchardp​​(ak)∣∣I2LEBSPℓbaseOrchardp​​(nk), where ak, nk are Pallas base field elements, and ℓbaseOrchardp​=255. Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into chunks: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=a∣∣b0​∣∣b1​=(bits 0..=249 of ak)∣∣(bits 250..=253 of ak)∣∣(bit 254 of ak)=b2​∣∣c∣∣d0​∣∣d1​=(bits 0..=4 of nk)∣∣(bits 5..=244 of nk)∣∣(bits 245..=253 of nk)∣∣(bit 254 of nk)​​ Then we recompose the chunks into message pieces: Length (bits)2501024010​Pieceab=b0​∣∣b1​∣∣b2​cd=d0​∣∣d1​​​ Each message piece is constrained by SinsemillaHash to its stated length. Additionally, ak and nk are witnessed as field elements, so we know they are canonical. However, we need additional constraints to enforce that: The chunks are the correct bit lengths (or else they could overlap in the decompositions and allow the prover to witness an arbitrary SinsemillaShortCommit message). The chunks contain the canonical decompositions of ak and nk (or else the prover could witness an input to SinsemillaShortCommit that is equivalent to ak and nk but not identical). Some of these constraints can be implemented with reusable circuit gadgets. We define a custom gate controlled by the selector qCommitivk​ to hold the remaining constraints.","breadcrumbs":"Design » Circuit » CommitIvk » Message decomposition","id":"36","title":"Message decomposition"},"37":{"body":"Chunks a and c are directly constrained by Sinsemilla. For the remaining chunks, we use the following constraints: Degree33​Constraintshort_lookup_range_check(b0​,4)short_lookup_range_check(b2​,5)short_lookup_range_check(d0​,9)qCommitivk​⋅bool_check(b1​)=0qCommitivk​⋅bool_check(d1​)=0​​ where bool_check(x)=x⋅(1−x) and short_lookup_range_check() is a short lookup range check .","breadcrumbs":"Design » Circuit » CommitIvk » Bit length constraints","id":"37","title":"Bit length constraints"},"38":{"body":"We have now derived or witnessed every subpiece, and range-constrained every subpiece: a (250 bits) is witnessed and constrained outside the gate; b0​ (4 bits) is witnessed and constrained outside the gate; b1​ (1 bits) is witnessed and boolean-constrained in the gate; b2​ (5 bits) is witnessed and constrained outside the gate; c (240 bits) is witnessed and constrained outside the gate; d0​ (9 bits) is witnessed and constrained outside the gate; d1​ (1 bits) is witnessed and boolean-constrained in the gate. We can now use them to reconstruct both the (chunked) message pieces, and the original field element inputs: bdaknk​=b0​+24⋅b1​+25⋅b2​=d0​+29⋅d1​=a+2250⋅b0​+2254⋅b1​=b2​+25⋅c+2245⋅d0​+2254⋅d1​​​ Degree2222​ConstraintqCommitivk​⋅(b−(b0​+b1​⋅24+b2​⋅25))=0qCommitivk​⋅(d−(d0​+d1​⋅29))=0qCommitivk​⋅(a+b0​⋅2250+b1​⋅2254−ak)=0qCommitivk​⋅(b2​+c⋅25+d0​⋅2245+d1​⋅2254−nk)=0​​","breadcrumbs":"Design » Circuit » CommitIvk » Decomposition constraints","id":"38","title":"Decomposition constraints"},"39":{"body":"At this point, we have constrained I2LEBSPℓbaseOrchardp​​(ak) and I2LEBSPℓbaseOrchardp​​(nk) to be 255-bit values, with top bits b1​ and d1​ respectively. We have also constrained: I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​=ak(modqP​)=nk(modqP​)​​ where qP​ is the Pallas base field modulus. The remaining constraints will enforce that these are indeed canonically-encoded field elements, i.e. I2LEBSPℓbaseOrchardp​​(ak)I2LEBSPℓbaseOrchardp​​(nk)​ - + User Documentation - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/user/creating-notes.html b/user/creating-notes.html index 540113f2..c0e86c09 100644 --- a/user/creating-notes.html +++ b/user/creating-notes.html @@ -1,40 +1,27 @@ - + Creating notes - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/user/integration.html b/user/integration.html index 028f90b4..56b9b9e2 100644 --- a/user/integration.html +++ b/user/integration.html @@ -1,40 +1,27 @@ - + Integration into an existing chain - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/user/keys.html b/user/keys.html index 0555c8d0..159fab62 100644 --- a/user/keys.html +++ b/user/keys.html @@ -1,40 +1,27 @@ - + Creating keys and addresses - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - - diff --git a/user/spending-notes.html b/user/spending-notes.html index 61c1a5e1..41c64f90 100644 --- a/user/spending-notes.html +++ b/user/spending-notes.html @@ -1,40 +1,27 @@ - + Spending notes - The Orchard Book - - - - - - + - - - - - - - - @@ -42,19 +29,18 @@ - - - + +
- - - + + - + + +
- - -