├── CODEOWNERS ├── themes └── book │ ├── layouts │ ├── partials │ │ └── docs │ │ │ ├── inject │ │ │ ├── body.html │ │ │ ├── menu-after.html │ │ │ ├── menu-before.html │ │ │ ├── toc-after.html │ │ │ ├── toc-before.html │ │ │ ├── content-after.html │ │ │ ├── content-before.html │ │ │ ├── head.html │ │ │ └── footer.html │ │ │ ├── html-head-title.html │ │ │ ├── toc.html │ │ │ ├── comments.html │ │ │ ├── date.html │ │ │ ├── menu-bundle.html │ │ │ ├── search.html │ │ │ ├── title.html │ │ │ ├── brand.html │ │ │ ├── taxonomy.html │ │ │ ├── post-meta.html │ │ │ ├── menu-hugo.html │ │ │ ├── menu.html │ │ │ ├── languages.html │ │ │ ├── footer.html │ │ │ ├── menu-filetree.html │ │ │ ├── html-head.html │ │ │ └── header.html │ ├── _default │ │ ├── list.html │ │ ├── single.html │ │ ├── _markup │ │ │ ├── render-heading.html │ │ │ ├── render-image.html │ │ │ └── render-link.html │ │ └── baseof.html │ ├── shortcodes │ │ ├── box.html │ │ ├── hint.html │ │ ├── section_entry.html │ │ ├── cite.html │ │ ├── columns.html │ │ ├── section.html │ │ ├── details.html │ │ ├── references.html │ │ ├── tab.html │ │ ├── button.html │ │ ├── mermaid.html │ │ ├── expand.html │ │ ├── tabs.html │ │ └── katex.html │ ├── posts │ │ ├── single.html │ │ └── list.html │ ├── taxonomy │ │ ├── list.html │ │ └── taxonomy.html │ └── 404.html │ ├── go.mod │ ├── assets │ ├── themes │ │ ├── _dark.scss │ │ ├── _light.scss │ │ └── _auto.scss │ ├── _variables.scss │ ├── mermaid.json │ ├── _custom.scss │ ├── sw-register.js │ ├── menu-reset.js │ ├── _print.scss │ ├── book.scss │ ├── manifest.json │ ├── plugins │ │ ├── _scrollbars.scss │ │ └── _numbered.scss │ ├── clipboard.js │ ├── search-data.json │ ├── _fonts.scss │ ├── sw.js │ ├── _utils.scss │ ├── _defaults.scss │ ├── _shortcodes.scss │ ├── search.js │ ├── _markdown.scss │ ├── normalize.css │ └── _main.scss │ ├── images │ ├── tn.png │ └── screenshot.png │ ├── static │ ├── favicon.png │ ├── fonts │ │ ├── roboto-v27-latin-700.woff │ │ ├── roboto-v27-latin-700.woff2 │ │ ├── roboto-v27-latin-regular.woff │ │ ├── roboto-v27-latin-regular.woff2 │ │ ├── roboto-mono-v13-latin-regular.woff │ │ └── roboto-mono-v13-latin-regular.woff2 │ ├── katex │ │ ├── fonts │ │ │ ├── KaTeX_AMS-Regular.ttf │ │ │ ├── KaTeX_Main-Bold.ttf │ │ │ ├── KaTeX_Main-Bold.woff │ │ │ ├── KaTeX_Main-Bold.woff2 │ │ │ ├── KaTeX_Main-Italic.ttf │ │ │ ├── KaTeX_Math-Italic.ttf │ │ │ ├── KaTeX_AMS-Regular.woff │ │ │ ├── KaTeX_AMS-Regular.woff2 │ │ │ ├── KaTeX_Fraktur-Bold.ttf │ │ │ ├── KaTeX_Fraktur-Bold.woff │ │ │ ├── KaTeX_Main-Italic.woff │ │ │ ├── KaTeX_Main-Italic.woff2 │ │ │ ├── KaTeX_Main-Regular.ttf │ │ │ ├── KaTeX_Main-Regular.woff │ │ │ ├── KaTeX_Math-Italic.woff │ │ │ ├── KaTeX_Math-Italic.woff2 │ │ │ ├── KaTeX_Size1-Regular.ttf │ │ │ ├── KaTeX_Size2-Regular.ttf │ │ │ ├── KaTeX_Size3-Regular.ttf │ │ │ ├── KaTeX_Size4-Regular.ttf │ │ │ ├── KaTeX_Caligraphic-Bold.ttf │ │ │ ├── KaTeX_Fraktur-Bold.woff2 │ │ │ ├── KaTeX_Fraktur-Regular.ttf │ │ │ ├── KaTeX_Fraktur-Regular.woff │ │ │ ├── KaTeX_Main-BoldItalic.ttf │ │ │ ├── KaTeX_Main-BoldItalic.woff │ │ │ ├── KaTeX_Main-Regular.woff2 │ │ │ ├── KaTeX_Math-BoldItalic.ttf │ │ │ ├── KaTeX_Math-BoldItalic.woff │ │ │ ├── KaTeX_SansSerif-Bold.ttf │ │ │ ├── KaTeX_SansSerif-Bold.woff │ │ │ ├── KaTeX_SansSerif-Bold.woff2 │ │ │ ├── KaTeX_SansSerif-Italic.ttf │ │ │ ├── KaTeX_Script-Regular.ttf │ │ │ ├── KaTeX_Script-Regular.woff │ │ │ ├── KaTeX_Script-Regular.woff2 │ │ │ ├── KaTeX_Size1-Regular.woff │ │ │ ├── KaTeX_Size1-Regular.woff2 │ │ │ ├── KaTeX_Size2-Regular.woff │ │ │ ├── KaTeX_Size2-Regular.woff2 │ │ │ ├── KaTeX_Size3-Regular.woff │ │ │ ├── KaTeX_Size3-Regular.woff2 │ │ │ ├── KaTeX_Size4-Regular.woff │ │ │ ├── KaTeX_Size4-Regular.woff2 │ │ │ ├── KaTeX_Caligraphic-Bold.woff │ │ │ ├── KaTeX_Caligraphic-Bold.woff2 │ │ │ ├── KaTeX_Fraktur-Regular.woff2 │ │ │ ├── KaTeX_Main-BoldItalic.woff2 │ │ │ ├── KaTeX_Math-BoldItalic.woff2 │ │ │ ├── KaTeX_SansSerif-Italic.woff │ │ │ ├── KaTeX_SansSerif-Italic.woff2 │ │ │ ├── KaTeX_SansSerif-Regular.ttf │ │ │ ├── KaTeX_SansSerif-Regular.woff │ │ │ ├── KaTeX_Typewriter-Regular.ttf │ │ │ ├── KaTeX_Caligraphic-Regular.ttf │ │ │ ├── KaTeX_Caligraphic-Regular.woff │ │ │ ├── KaTeX_Caligraphic-Regular.woff2 │ │ │ ├── KaTeX_SansSerif-Regular.woff2 │ │ │ ├── KaTeX_Typewriter-Regular.woff │ │ │ └── KaTeX_Typewriter-Regular.woff2 │ │ └── auto-render.min.js │ ├── svg │ │ ├── menu.svg │ │ ├── toc.svg │ │ ├── calendar.svg │ │ ├── edit.svg │ │ └── translate.svg │ └── favicon.svg │ ├── archetypes │ ├── posts.md │ └── docs.md │ ├── i18n │ ├── en.yaml │ ├── nb.yaml │ ├── pt.yaml │ ├── tr.yaml │ ├── de.yaml │ ├── es.yaml │ ├── it.yaml │ ├── sv.yaml │ ├── cs.yaml │ ├── fr.yaml │ ├── bn.yaml │ ├── uk.yaml │ ├── ru.yaml │ ├── zh.yaml │ ├── ja.yaml │ ├── zh-TW.yaml │ ├── ko.yaml │ ├── cn.yaml │ ├── jp.yaml │ └── fa.yaml │ ├── .github │ └── workflows │ │ └── main.yml │ ├── theme.toml │ └── LICENSE ├── layouts └── shortcodes │ └── rawhtml.html ├── .gitignore ├── static ├── logo.png ├── figs │ └── demo.gif └── TOB_Black.svg ├── archetypes └── default.md ├── .github ├── dependabot.yml └── workflows │ └── gh-pages.yml ├── resources └── _gen │ └── assets │ └── scss │ └── book.scss_e129fe35b8d0a70789c8a08429469073.json ├── content ├── docs │ └── zkdocs │ │ ├── protocol-primitives │ │ ├── _index.md │ │ ├── nums.md │ │ ├── verifiable-secret-sharing.md │ │ ├── alt-shamir.md │ │ ├── fiat-shamir.md │ │ └── shamir.md │ │ ├── bibliography.md │ │ ├── Generic zero-knowledge systems │ │ └── _index.md │ │ ├── zero-knowledge-protocols │ │ ├── _index.md │ │ ├── product-primes │ │ │ ├── _index.md │ │ │ ├── square-freeness.md │ │ │ └── product-of-two-primes.md │ │ ├── girault-identification.md │ │ ├── schnorr-variants.md │ │ └── schnorr.md │ │ ├── security-of-zkps │ │ ├── _index.md │ │ └── when-to-use-hvzk.md │ │ ├── template.md │ │ ├── _index.md │ │ ├── notation.md │ │ └── commitments │ │ └── _index.md └── _index.md ├── config.toml └── README.md /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @fcasal 2 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/body.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/menu-after.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/menu-before.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/toc-after.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/toc-before.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/shortcodes/rawhtml.html: -------------------------------------------------------------------------------- 1 | 2 | {{.Inner}} -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/content-after.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/content-before.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{ define "dummy" }}{{ end }} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | exampleSite/public/ 3 | .DS_Store 4 | node_modules/* -------------------------------------------------------------------------------- /themes/book/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/alex-shpak/hugo-book 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /themes/book/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "dummy" }}{{ end }} 2 | -------------------------------------------------------------------------------- /themes/book/assets/themes/_dark.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | @include theme-dark; 3 | } 4 | -------------------------------------------------------------------------------- /themes/book/assets/themes/_light.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | @include theme-light; 3 | } 4 | -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/static/logo.png -------------------------------------------------------------------------------- /static/figs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/static/figs/demo.gif -------------------------------------------------------------------------------- /themes/book/images/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/images/tn.png -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/html-head-title.html: -------------------------------------------------------------------------------- 1 | {{ partial "docs/title" . }} | {{ .Site.Title -}} 2 | -------------------------------------------------------------------------------- /themes/book/assets/_variables.scss: -------------------------------------------------------------------------------- 1 | /* You can override SASS variables here. */ 2 | 3 | // @import "plugins/dark"; 4 | -------------------------------------------------------------------------------- /themes/book/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/favicon.png -------------------------------------------------------------------------------- /themes/book/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/images/screenshot.png -------------------------------------------------------------------------------- /themes/book/assets/mermaid.json: -------------------------------------------------------------------------------- 1 | { 2 | "flowchart": { 3 | "useMaxWidth":true 4 | }, 5 | "theme": "default" 6 | } 7 | -------------------------------------------------------------------------------- /archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/box.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .Inner | .Page.RenderString }} 3 |
4 | -------------------------------------------------------------------------------- /themes/book/assets/_custom.scss: -------------------------------------------------------------------------------- 1 | /* You can add custom styles here. */ 2 | 3 | // @import "plugins/numbered"; 4 | @import "plugins/scrollbars"; 5 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/hint.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .Inner | .Page.RenderString }} 3 |
4 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/toc.html: -------------------------------------------------------------------------------- 1 | {{ partial "docs/inject/toc-before" . }} 2 | {{ .TableOfContents }} 3 | {{ partial "docs/inject/toc-after" . }} 4 | -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-v27-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-v27-latin-700.woff -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-v27-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-v27-latin-700.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_AMS-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_AMS-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Bold.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Bold.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Bold.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Italic.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-Italic.ttf -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-v27-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-v27-latin-regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_AMS-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_AMS-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_AMS-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_AMS-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Italic.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Italic.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-Italic.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-Italic.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size1-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size1-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size2-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size2-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size3-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size3-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size4-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size4-Regular.ttf -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/head.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-v27-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-v27-latin-regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Script-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Script-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Script-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Script-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Script-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Script-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size1-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size1-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size1-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size1-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size2-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size2-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size2-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size2-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size3-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size3-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size3-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size3-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size4-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size4-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Size4-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Size4-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/archetypes/posts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ .Name | humanize | title }}" 3 | date: {{ .Date }} 4 | # bookComments: false 5 | # bookSearchExclude: false 6 | --- 7 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/comments.html: -------------------------------------------------------------------------------- 1 | 2 | {{ template "_internal/disqus.html" . }} 3 | -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-mono-v13-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-mono-v13-latin-regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/fonts/roboto-mono-v13-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/fonts/roboto-mono-v13-latin-regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.woff -------------------------------------------------------------------------------- /themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trailofbits/zkdocs/HEAD/themes/book/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 -------------------------------------------------------------------------------- /themes/book/assets/themes/_auto.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | @include theme-light; 3 | } 4 | 5 | @media (prefers-color-scheme: dark) { 6 | :root { 7 | @include theme-dark; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /themes/book/layouts/_default/_markup/render-heading.html: -------------------------------------------------------------------------------- 1 | 2 | {{ .Text | safeHTML }} 3 | # 4 | 5 | -------------------------------------------------------------------------------- /themes/book/static/svg/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/section_entry.html: -------------------------------------------------------------------------------- 1 |
2 | {{ $name := .Get 0 }} 3 | {{ $t := .Site.GetPage $name }} 4 |
5 | {{ partial "docs/title" $t }} 6 |
7 |
8 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/cite.html: -------------------------------------------------------------------------------- 1 | {{ $ref := .Get 0}} 2 | {{ $details := index $.Site.Data.references $ref }} 3 | {{if $details }} 4 | [{{$details.tag}}] 5 | {{end}} -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/columns.html: -------------------------------------------------------------------------------- 1 |
2 | {{ range split .Inner "<--->" }} 3 |
4 | {{ . | $.Page.RenderString }} 5 |
6 | {{ end }} 7 |
8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | groups: 8 | github-actions: 9 | patterns: 10 | - "*" 11 | -------------------------------------------------------------------------------- /themes/book/static/svg/toc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/_gen/assets/scss/book.scss_e129fe35b8d0a70789c8a08429469073.json: -------------------------------------------------------------------------------- 1 | {"Target":"book.min.6aece0f96007af353373ec1c05beb9d415830db47ac294f964054d8382bbb1e3.css","MediaType":"text/css","Data":{"Integrity":"sha256-auzg+WAHrzUzc+wcBb651BWDDbR6wpT5ZAVNg4K7seM="}} -------------------------------------------------------------------------------- /themes/book/archetypes/docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ .Name | humanize | title }}" 3 | weight: 1 4 | # bookFlatSection: false 5 | # bookToc: true 6 | # bookHidden: false 7 | # bookCollapseSection: false 8 | # bookComments: false 9 | # bookSearchExclude: false 10 | --- 11 | -------------------------------------------------------------------------------- /themes/book/assets/sw-register.js: -------------------------------------------------------------------------------- 1 | {{- $swJS := resources.Get "sw.js" | resources.ExecuteAsTemplate "sw.js" . -}} 2 | if (navigator.serviceWorker) { 3 | navigator.serviceWorker.register( 4 | "{{ $swJS.RelPermalink }}", 5 | { scope: "{{ "/" | relURL }}" } 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/date.html: -------------------------------------------------------------------------------- 1 | 5 | {{- $format := default "January 2, 2006" .Format -}} 6 | {{- return (.Date.Format $format) -}} 7 | -------------------------------------------------------------------------------- /themes/book/static/svg/calendar.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 3 3 | bookFlatSection: true 4 | title: "Protocol primitives" 5 | --- 6 | 7 | # Protocol primitives 8 | 9 | In this section, we detail commonly used primitives in zero-knowledge protocols. 10 | 11 | {{
}} 12 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/section.html: -------------------------------------------------------------------------------- 1 |
2 | {{ range .Page.Pages }} 3 |
4 | {{ partial "docs/title" . }} 5 |
6 |
7 | {{ default .Summary .Description }} 8 |
9 | {{ end }} 10 |
11 | -------------------------------------------------------------------------------- /content/docs/zkdocs/bibliography.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 20 3 | bookFlatSection: true 4 | title: "Bibliography" 5 | summary: "All references" 6 | --- 7 | 8 | # References 9 | Here, we gather a list with all references used throughout the website, sorted by year. 10 | 11 | {{< references >}} 12 | 13 | 14 | -------------------------------------------------------------------------------- /themes/book/static/svg/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/assets/menu-reset.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var menu = document.querySelector("aside .book-menu-content"); 3 | addEventListener("beforeunload", function(event) { 4 | localStorage.setItem("menu.scrollTop", menu.scrollTop); 5 | }); 6 | menu.scrollTop = localStorage.getItem("menu.scrollTop"); 7 | })(); 8 | -------------------------------------------------------------------------------- /content/docs/zkdocs/Generic zero-knowledge systems/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 3 3 | bookFlatSection: true 4 | title: "Protocol primitives" 5 | draft: true 6 | --- 7 | 8 | # Protocol primitives 9 | 10 | In this section we detail useful and commonly used primitives for zero-knowledge protocols. 11 | 12 | {{
}} 13 | -------------------------------------------------------------------------------- /themes/book/i18n/en.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Search 3 | 4 | - id: Edit this page 5 | translation: Edit this page 6 | 7 | - id: Last modified by 8 | translation: Last modified by 9 | 10 | - id: Expand 11 | translation: Expand 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/nb.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Søk 3 | 4 | - id: Edit this page 5 | translation: Rediger denne siden 6 | 7 | - id: Last modified by 8 | translation: Sist endret av 9 | 10 | - id: Expand 11 | translation: Utvid 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/menu-bundle.html: -------------------------------------------------------------------------------- 1 | {{ with .Site.GetPage .Site.Params.BookMenuBundle }} 2 | {{- $href := printf "href=\"%s\"" $.RelPermalink -}} 3 | {{- replace .Content $href (print $href "class=active") | safeHTML -}} 4 | {{- warnf "Bundle menu mode is deprecated and will be removed" -}} 5 | {{ end }} 6 | -------------------------------------------------------------------------------- /themes/book/i18n/pt.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Buscar 3 | 4 | - id: Edit this page 5 | translation: Editar página 6 | 7 | - id: Last modified by 8 | translation: Última modificação por 9 | 10 | - id: Expand 11 | translation: Expandir 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/tr.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Arama 3 | 4 | - id: Edit this page 5 | translation: Bu sayfayı düzenle 6 | 7 | - id: Last modified by 8 | translation: Son düzenleyen 9 | 10 | - id: Expand 11 | translation: Genişlet 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/de.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Suche 3 | 4 | - id: Edit this page 5 | translation: Seite bearbeiten 6 | 7 | - id: Last modified by 8 | translation: Zuletzt geändert von 9 | 10 | - id: Expand 11 | translation: Erweitern 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/es.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Buscar 3 | 4 | - id: Edit this page 5 | translation: Editar esta página 6 | 7 | - id: Last modified by 8 | translation: Última modificación por 9 | 10 | - id: Expand 11 | translation: Expand 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/it.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Cerca 3 | 4 | - id: Edit this page 5 | translation: Modifica questa pagina 6 | 7 | - id: Last modified by 8 | translation: Ultima modifica di 9 | 10 | - id: Expand 11 | translation: Espandi 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/sv.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Sök 3 | 4 | - id: Edit this page 5 | translation: Redigera denna sida 6 | 7 | - id: Last modified by 8 | translation: Senast modifierad av 9 | 10 | - id: Expand 11 | translation: Expandera 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/cs.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Vyhledávat 3 | 4 | - id: Edit this page 5 | translation: Upravit tuto stránku 6 | 7 | - id: Last modified by 8 | translation: Autor poslední změny 9 | 10 | - id: Expand 11 | translation: Rozbalit 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/fr.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Rechercher 3 | 4 | - id: Edit this page 5 | translation: Modifier cette page 6 | 7 | - id: Last modified by 8 | translation: Dernière modification par 9 | 10 | - id: Expand 11 | translation: Développer 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/details.html: -------------------------------------------------------------------------------- 1 |
2 | {{- $summary := cond .IsNamedParams (.Get "title") (.Get 0) -}} 3 | {{ $summary | .Page.RenderString }} 4 |
5 | {{ .Inner | .Page.RenderString }} 6 |
7 |
8 | -------------------------------------------------------------------------------- /themes/book/i18n/bn.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: অনুসন্ধান 3 | 4 | - id: Edit this page 5 | translation: এই পৃষ্ঠাটি সম্পাদনা করুন 6 | 7 | - id: Last modified by 8 | translation: সর্বশেষ সম্পাদনা করেছেন 9 | 10 | - id: Expand 11 | translation: বিস্তৃত করা 12 | 13 | - id: bookSearchConfig 14 | translation: '{ cache: true }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/uk.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Пошук 3 | 4 | - id: Edit this page 5 | translation: Редагувати цю сторінку 6 | 7 | - id: Last modified by 8 | translation: Остання зміна від 9 | 10 | - id: Expand 11 | translation: Розгорнути 12 | 13 | - id: bookSearchConfig 14 | translation: '{ split: /[^a-zа-яё0-9\w]/gi }' 15 | -------------------------------------------------------------------------------- /themes/book/i18n/ru.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Поиск 3 | 4 | - id: Edit this page 5 | translation: Редактировать эту страницу 6 | 7 | - id: Last modified by 8 | translation: Последнее изменение от 9 | 10 | - id: Expand 11 | translation: Развернуть 12 | 13 | - id: bookSearchConfig 14 | translation: '{ split: /[^a-zа-яё0-9\w]/gi }' 15 | -------------------------------------------------------------------------------- /themes/book/layouts/posts/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | 9 | {{ end }} 10 | 11 | {{ define "toc" }} 12 | {{ partial "docs/toc" . }} 13 | {{ end }} 14 | -------------------------------------------------------------------------------- /themes/book/assets/_print.scss: -------------------------------------------------------------------------------- 1 | @media print { 2 | .book-menu, 3 | .book-footer, 4 | .book-toc { 5 | display: none; 6 | } 7 | 8 | .book-header, 9 | .book-header aside { 10 | display: block; 11 | } 12 | 13 | main { 14 | // Fix for https://bugzilla.mozilla.org/show_bug.cgi?id=939897 15 | display: block !important; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /themes/book/assets/book.scss: -------------------------------------------------------------------------------- 1 | @import "defaults"; 2 | @import "variables"; 3 | @import "themes/{{ default "light" .Site.Params.BookTheme }}"; 4 | 5 | @import "normalize"; 6 | @import "utils"; 7 | @import "main"; 8 | @import "fonts"; 9 | @import "print"; 10 | 11 | @import "markdown"; 12 | @import "shortcodes"; 13 | 14 | // Custom defined styles 15 | @import "custom"; 16 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/references.html: -------------------------------------------------------------------------------- 1 | {{range $details := sort .Site.Data.references "year"}} 2 | {{if $details.apa}} 3 | 6 | {{end}} 7 | {{end}} -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/search.html: -------------------------------------------------------------------------------- 1 | {{ if default true .Site.Params.BookSearch }} 2 | 7 | {{ end }} 8 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "Zero-knowledge protocols" 5 | --- 6 | 7 | # Zero-knowledge protocols 8 | 9 | Here, we provide uniform, detailed descriptions to several zero-knowledge protocols. We include: necessary setup, security pitfalls and associated severity, safe parameter choices, and original references. 10 | 11 | {{
}} -------------------------------------------------------------------------------- /themes/book/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ .Site.Title }}", 3 | "short_name": "{{ .Site.Title }}", 4 | "start_url": "{{ "/" | relURL }}", 5 | "scope": "{{ "/" | relURL }}", 6 | "display": "standalone", 7 | "background_color": "#000000", 8 | "theme_color": "#000000", 9 | "icons": [ 10 | { 11 | "src": "{{ "/favicon.svg" | relURL }}", 12 | "sizes": "512x512" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /themes/book/i18n/zh.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: 搜索 3 | 4 | - id: Edit this page 5 | translation: 编辑本页 6 | 7 | - id: Last modified by 8 | translation: 最后修改者 9 | 10 | - id: Expand 11 | translation: 展开 12 | 13 | - id: bookSearchConfig 14 | translation: | 15 | { 16 | encode: false, 17 | tokenize: function(str) { 18 | return str.replace(/[\x00-\x7F]/g, '').split(''); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /themes/book/i18n/ja.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: 検索 3 | 4 | - id: Edit this page 5 | translation: このページを編集する 6 | 7 | - id: Last modified by 8 | translation: 最終更新者 9 | 10 | - id: Expand 11 | translation: 展開 12 | 13 | - id: bookSearchConfig 14 | translation: | 15 | { 16 | encode: false, 17 | tokenize: function(str) { 18 | return str.replace(/[\x00-\x7F]/g, '').split(''); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /themes/book/i18n/zh-TW.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: 搜索 3 | 4 | - id: Edit this page 5 | translation: 編輯頁面 6 | 7 | - id: Last modified by 8 | translation: 最後修改者 9 | 10 | - id: Expand 11 | translation: 展開 12 | 13 | - id: bookSearchConfig 14 | translation: | 15 | { 16 | encode: false, 17 | tokenize: function(str) { 18 | return str.replace(/[\x00-\x7F]/g, '').split(''); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /themes/book/layouts/taxonomy/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |

{{ .Title | title }}

4 | {{ $taxonomies := index .Site.Taxonomies .Page.Type }} 5 | {{ range $taxonomies }} 6 |
{{ .Page.Title }} {{ .Count }}
7 | {{ end }} 8 |
9 | {{ end }} 10 | 11 | {{ define "toc" }} 12 | {{ partial "docs/taxonomy" . }} 13 | {{ end }} 14 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/tab.html: -------------------------------------------------------------------------------- 1 | {{ if .Parent }} 2 | {{ $name := .Get 0 }} 3 | {{ $group := printf "tabs-%s" (.Parent.Get 0) }} 4 | 5 | {{ if not (.Parent.Scratch.Get $group) }} 6 | {{ .Parent.Scratch.Set $group slice }} 7 | {{ end }} 8 | 9 | {{ .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }} 10 | {{ else }} 11 | {{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }} 12 | {{ end}} 13 | -------------------------------------------------------------------------------- /themes/book/static/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /themes/book/static/svg/translate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/book/i18n/ko.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: Search 3 | 4 | - id: Edit this page 5 | translation: Edit this page 6 | 7 | - id: Last modified by 8 | translation: Last modified by 9 | 10 | - id: Expand 11 | translation: Expand 12 | 13 | - id: bookSearchConfig 14 | translation: | 15 | { 16 | encode: false, 17 | tokenize: function(str) { 18 | return str.replace(/[\x00-\x7F]/g, '').split(''); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/button.html: -------------------------------------------------------------------------------- 1 | {{ $ref := "" }} 2 | {{ $target := "" }} 3 | {{ with .Get "href" }} 4 | {{ $ref = . }} 5 | {{ $target = "_blank" }} 6 | {{ end }} 7 | {{ with .Get "relref" }} 8 | {{ $ref = relref $ . }} 9 | {{ end }} 10 | 11 | {{ .Inner | .Page.RenderString }} 12 | 13 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/title.html: -------------------------------------------------------------------------------- 1 | 5 | {{ $title := "" }} 6 | 7 | {{ if .Title }} 8 | {{ $title = .Title }} 9 | {{ else if and .IsSection .File }} 10 | {{ $title = path.Base .File.Dir | humanize | title }} 11 | {{ else if and .IsPage .File }} 12 | {{ $title = .File.BaseFileName | humanize | title }} 13 | {{ end }} 14 | 15 | {{ return $title }} 16 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/mermaid.html: -------------------------------------------------------------------------------- 1 | {{ if not (.Page.Scratch.Get "mermaid") }} 2 | 3 | 4 | {{ with resources.Get "mermaid.json" }} 5 | 6 | {{ end }} 7 | {{ .Page.Scratch.Set "mermaid" true }} 8 | {{ end }} 9 | 10 |

11 | {{- .Inner -}} 12 |

13 | -------------------------------------------------------------------------------- /themes/book/i18n/cn.yaml: -------------------------------------------------------------------------------- 1 | # This should be removed in future, 'cn' is moved to `zh' 2 | - id: Search 3 | translation: 搜索 4 | 5 | - id: Edit this page 6 | translation: 编辑本页 7 | 8 | - id: Last modified by 9 | translation: 最后修改者 10 | 11 | - id: Expand 12 | translation: 展开 13 | 14 | - id: bookSearchConfig 15 | translation: | 16 | { 17 | encode: false, 18 | tokenize: function(str) { 19 | return str.replace(/[\x00-\x7F]/g, '').split(''); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /themes/book/i18n/jp.yaml: -------------------------------------------------------------------------------- 1 | # This should be removed in future, 'jp' is moved to `ja' 2 | - id: Search 3 | translation: 検索 4 | 5 | - id: Edit this page 6 | translation: このページを編集する 7 | 8 | - id: Last modified by 9 | translation: 最終更新者 10 | 11 | - id: Expand 12 | translation: 展開 13 | 14 | - id: bookSearchConfig 15 | translation: | 16 | { 17 | encode: false, 18 | tokenize: function(str) { 19 | return str.replace(/[\x00-\x7F]/g, '').split(''); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /themes/book/i18n/fa.yaml: -------------------------------------------------------------------------------- 1 | - id: Search 2 | translation: جستجو 3 | 4 | - id: Edit this page 5 | translation: این صفحه را ویرایش کنید 6 | 7 | - id: Last modified by 8 | translation: آخرین بار ویرایش شده توسط 9 | 10 | - id: Expand 11 | translation: بسط دادن 12 | 13 | - id: Categories 14 | translation: دسته بندی ها 15 | 16 | - id: Tags 17 | translation: تگ ها 18 | 19 | - id: bookSearchConfig 20 | translation: '{ cache: true, encode: false, rtl: true, split: /\s+/, tokenize: "forward"}' 21 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/expand.html: -------------------------------------------------------------------------------- 1 | {{ warnf "Expand shortcode is deprecated. Use 'details' instead." }} 2 |
3 | 13 |
14 | -------------------------------------------------------------------------------- /content/docs/zkdocs/security-of-zkps/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 2 3 | bookFlatSection: true 4 | title: "Security of ZKPs" 5 | --- 6 | 7 | # Security of ZKPs and their implementations 8 | 9 | Here we present several security issues with implementations of zero-knowledge protocols, Fiat-Shamir transformations, and what can happen when interactive zero-knowledge proof systems are used in the context of malicious adversaries. 10 | 11 | {{
}} 12 | 13 | #### See also: 14 | - {{< section_entry "docs/zkdocs/protocol-primitives/fiat-shamir" >}} -------------------------------------------------------------------------------- /themes/book/assets/plugins/_scrollbars.scss: -------------------------------------------------------------------------------- 1 | @import "defaults"; 2 | @import "variables"; 3 | 4 | // Webkit 5 | ::-webkit-scrollbar { 6 | width: $padding-8; 7 | } 8 | 9 | ::-webkit-scrollbar-thumb { 10 | background: transparent; 11 | border-radius: $padding-8; 12 | } 13 | 14 | :hover::-webkit-scrollbar-thumb { 15 | background: var(--gray-500); 16 | } 17 | 18 | // MS 19 | body { 20 | -ms-overflow-style: -ms-autohiding-scrollbar; 21 | } 22 | 23 | // Future 24 | .book-menu nav { 25 | scrollbar-color: transparent var(--gray-500); 26 | } 27 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/brand.html: -------------------------------------------------------------------------------- 1 |

2 | 4 | {{- with .Site.Params.BookLogo -}} 5 | Logo 6 | {{- end -}} 7 |
8 | {{- with .Site.Params.BookIconLogo -}} 9 | 10 | {{- end -}} 11 | {{ .Site.Title }} 12 |
13 |
14 |

-------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/taxonomy.html: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | googleAnalytics = "UA-215689345-1" 2 | baseURL = 'https://www.zkdocs.com' 3 | languageCode = 'en-us' 4 | title = 'ZKDocs' 5 | theme = "book" 6 | [params] 7 | BookLogo = 'TOB_Black.svg' 8 | BookIconLogo = 'logo.png' 9 | 10 | [markup] 11 | [markup.highlight] 12 | anchorLineNos = false 13 | codeFences = true 14 | guessSyntax = false 15 | hl_Lines = '' 16 | lineAnchors = '' 17 | lineNoStart = 1 18 | lineNos = true 19 | lineNumbersInTable = true 20 | noClasses = true 21 | style = 'friendly' 22 | # style = 'pastie' 23 | tabWidth = 4 24 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/tabs.html: -------------------------------------------------------------------------------- 1 | {{ if .Inner }}{{ end }} 2 | {{ $id := .Get 0 }} 3 | {{ $group := printf "tabs-%s" $id }} 4 | 5 |
6 | {{- range $index, $tab := .Scratch.Get $group -}} 7 | 8 | 11 |
12 | {{- .Content | $.Page.RenderString -}} 13 |
14 | {{- end -}} 15 |
16 | -------------------------------------------------------------------------------- /themes/book/.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build with Hugo 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | hugo-version: 11 | - 'latest' 12 | - '0.68.0' 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Setup Hugo 17 | uses: peaceiris/actions-hugo@v2 18 | with: 19 | hugo-version: ${{ matrix.hugo-version }} 20 | extended: true 21 | 22 | - name: Run Hugo 23 | working-directory: exampleSite 24 | run: hugo --themesDir ../.. 25 | -------------------------------------------------------------------------------- /themes/book/layouts/posts/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ range sort .Paginator.Pages }} 3 | 15 | {{ end }} 16 | 17 | {{ template "_internal/pagination.html" . }} 18 | {{ end }} 19 | 20 | {{ define "toc" }} 21 | {{ partial "docs/taxonomy" . }} 22 | {{ end }} 23 | -------------------------------------------------------------------------------- /themes/book/layouts/taxonomy/taxonomy.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ range sort .Paginator.Pages }} 3 | 15 | {{ end }} 16 | 17 | {{ template "_internal/pagination.html" . }} 18 | {{ end }} 19 | 20 | {{ define "toc" }} 21 | {{ partial "docs/taxonomy" . }} 22 | {{ end }} 23 | -------------------------------------------------------------------------------- /themes/book/assets/clipboard.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function select(element) { 3 | const selection = window.getSelection(); 4 | 5 | const range = document.createRange(); 6 | range.selectNodeContents(element); 7 | 8 | selection.removeAllRanges(); 9 | selection.addRange(range); 10 | } 11 | 12 | document.querySelectorAll("pre code").forEach(code => { 13 | code.addEventListener("click", function (event) { 14 | select(code.parentElement); 15 | 16 | if (navigator.clipboard) { 17 | navigator.clipboard.writeText(code.parentElement.textContent); 18 | } 19 | }); 20 | }); 21 | })(); 22 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/inject/footer.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /themes/book/layouts/shortcodes/katex.html: -------------------------------------------------------------------------------- 1 | {{- if not (.Page.Scratch.Get "katex") -}} 2 | 3 | 4 | 5 | 6 | {{- .Page.Scratch.Set "katex" true -}} 7 | {{- end -}} 8 | 9 | 10 | {{ cond (in .Params "display") "\\[" "\\(" -}} 11 | {{- trim .Inner "\n" -}} 12 | {{- cond (in .Params "display") "\\]" "\\)" }} 13 | 14 | -------------------------------------------------------------------------------- /themes/book/theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/gohugoio/hugoThemes#themetoml for an example 3 | 4 | name = "Book" 5 | license = "MIT" 6 | licenselink = "https://github.com/alex-shpak/hugo-book/blob/master/LICENSE" 7 | description = "Hugo documentation theme as simple as plain book" 8 | homepage = "https://github.com/alex-shpak/hugo-book" 9 | demosite = "https://hugo-book-demo.netlify.app" 10 | tags = ["responsive", "clean", "documentation", "docs", "flexbox", "search", "mobile", "multilingual", "disqus"] 11 | features = [] 12 | min_version = "0.68" 13 | 14 | [author] 15 | name = "Alex Shpak" 16 | homepage = "https://github.com/alex-shpak/" 17 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/post-meta.html: -------------------------------------------------------------------------------- 1 | {{ with .Date }} 2 |
{{ partial "docs/date" (dict "Date" . "Format" $.Site.Params.BookDateFormat) }}
3 | {{ end }} 4 | 5 | {{ range $taxonomy, $_ := .Site.Taxonomies }} 6 | {{ with $terms := $.GetTerms $taxonomy }} 7 |
8 | {{ range $n, $term := $terms }}{{ if $n }}, {{ end }} 9 | {{ $term.Title }} 10 | {{- end }} 11 |
12 | {{ end }} 13 | {{ end }} 14 | 15 | {{ if .Params.image }} 16 |

17 | {{ with .Resources.GetMatch .Params.image }} 18 | 19 | {{ else }} 20 | 21 | {{ end }} 22 |

23 | {{ end }} 24 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/menu-hugo.html: -------------------------------------------------------------------------------- 1 | 5 | {{ if . }} 6 | {{ template "book-menu-hugo" . }} 7 | {{ end }} 8 | 9 | {{ define "book-menu-hugo" }} 10 | 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /themes/book/assets/search-data.json: -------------------------------------------------------------------------------- 1 | [ 2 | {{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}} 3 | {{- $pages = where $pages "Params.booksearchexclude" "!=" true -}} 4 | {{/* Remove until we know why it does not work, see https://github.com/alex-shpak/hugo-book/issues/528 */}} 5 | {{/*- $pages = where $pages "Content" "not in" (slice nil "") -*/}} 6 | {{- $pages = where $pages "Content" "!=" "" -}} 7 | 8 | {{ range $index, $page := $pages }} 9 | {{ if gt $index 0}},{{end}} { 10 | "id": {{ $index }}, 11 | "href": "{{ $page.RelPermalink }}", 12 | "title": {{ (partial "docs/title" $page) | jsonify }}, 13 | "section": {{ (partial "docs/title" $page.Parent) | jsonify }}, 14 | "content": {{ $page.Plain | jsonify }} 15 | } 16 | {{- end -}} 17 | ] 18 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/menu.html: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | {{ $script := resources.Get "menu-reset.js" | resources.Minify }} 23 | {{ with $script.Content }} 24 | 25 | {{ end }} 26 | -------------------------------------------------------------------------------- /themes/book/assets/plugins/_numbered.scss: -------------------------------------------------------------------------------- 1 | $startLevel: 1; 2 | $endLevel: 6; 3 | 4 | .book-page .markdown { 5 | @for $currentLevel from $startLevel through $endLevel { 6 | > h#{$currentLevel} { 7 | counter-increment: h#{$currentLevel}; 8 | counter-reset: h#{$currentLevel + 1}; 9 | 10 | $content: ""; 11 | @for $n from $startLevel through $currentLevel { 12 | $content: $content + 'counter(h#{$n})"."'; 13 | } 14 | 15 | &::before { 16 | content: unquote($content) " "; 17 | } 18 | } 19 | } 20 | } 21 | 22 | .book-toc nav ul { 23 | li { 24 | counter-increment: item; 25 | 26 | &:first-child { 27 | counter-reset: item; 28 | } 29 | 30 | &:before { 31 | content: counters(item, ".") ". "; 32 | float: left; 33 | margin-inline-end: $padding-4; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /themes/book/layouts/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ partial "docs/html-head" . }} 6 | {{ partial "docs/inject/head" . }} 7 | 8 | 18 | 19 | 20 | 21 |
22 |
23 |

404

24 |

Page Not Found

25 |

26 | {{ .Site.Title }} 27 |

28 |
29 |
30 | 31 | {{ partial "docs/inject/body" . }} 32 | {{ template "_internal/google_analytics.html" . }} 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /themes/book/layouts/_default/_markup/render-image.html: -------------------------------------------------------------------------------- 1 | {{- if .Page.Site.Params.BookPortableLinks -}} 2 | {{- template "portable-image" . -}} 3 | {{- else -}} 4 | {{ .Text }} 5 | {{- end -}} 6 | 7 | {{- define "portable-image" -}} 8 | {{- $isRemote := or (in .Destination "://") (strings.HasPrefix .Destination "//") }} 9 | {{- if not $isRemote }} 10 | {{- $path := print .Page.File.Dir .Destination }} 11 | {{- if strings.HasPrefix .Destination "/" }} 12 | {{- $path = print "/static" .Destination }} 13 | {{- end }} 14 | {{- if not (fileExists $path) }} 15 | {{- warnf "Image '%s' not found in '%s'" .Destination .Page.File }} 16 | {{- end }} 17 | {{- end }} 18 | {{ .Text }} 19 | {{- end -}} 20 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/product-primes/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | bookCollapseSection: false 3 | weight: 3 4 | title: "Number is product of two primes" 5 | needsVariableResetButton: true 6 | summary: "Prove that a number is the product of two primes. We show two proofs of this: one for generic primes, and another, more efficient, when primes are congruent with 3 modulo 4." 7 | --- 8 | ## Product of primes 9 | One way to prove that some number $\varN$ is the product of two primes $\varN = \varp \varq$ is by showing that: 10 | - $\varN$ is square-free 11 | - $\varN$ only has two divisors 12 | 13 | If we only showed that $\varN$ is square-free, then it could be of the form $\varN = \varp \varq \varr$. 14 | On the other hand, if we only proved that $\varN$ has two divisors, it could be of the form $\varN = \varp^2\varq$. 15 | 16 | When the primes are congruent with $3 \\; \mathsf{mod}\\; 4$, we can show that $\varN$ is the product of two primes much more efficiently with the [Paillier-Blum modulus]({{< relref "/docs/zkdocs/zero-knowledge-protocols/product-primes/paillier_blum_modulus" >}}) proof. 17 | 18 | {{
}} 19 | -------------------------------------------------------------------------------- /themes/book/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Alex Shpak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/languages.html: -------------------------------------------------------------------------------- 1 | 2 | {{ $bookTranslatedOnly := default false .Site.Params.BookTranslatedOnly }} 3 | {{ $translations := dict }} 4 | {{ if (eq $bookTranslatedOnly false ) }} 5 | {{ range .Site.Home.Translations }} 6 | {{ $translations = merge $translations (dict .Language.Lang .) }} 7 | {{ end }} 8 | {{ end }} 9 | {{ range .Translations }} 10 | {{ $translations = merge $translations (dict .Language.Lang .) }} 11 | {{ end }} 12 | 13 | 34 | -------------------------------------------------------------------------------- /themes/book/layouts/_default/_markup/render-link.html: -------------------------------------------------------------------------------- 1 | {{- if .Page.Site.Params.BookPortableLinks -}} 2 | {{- template "portable-link" . -}} 3 | {{- else -}} 4 | {{ .Text | safeHTML }} 5 | {{- end -}} 6 | 7 | {{- define "portable-link" -}} 8 | {{- $destination := .Destination }} 9 | {{- $isRemote := or (in .Destination ":") (strings.HasPrefix .Destination "//") }} 10 | {{- if not $isRemote }} 11 | {{- $url := urls.Parse .Destination }} 12 | {{- $path := strings.TrimSuffix "/_index.md" $url.Path }} 13 | {{- $path = strings.TrimSuffix "/_index" $path }} 14 | {{- $path = strings.TrimSuffix ".md" $path }} 15 | {{- $page := .Page.GetPage $path }} 16 | {{- if $page }} 17 | {{- $destination = $page.RelPermalink }} 18 | {{- if $url.Fragment }} 19 | {{- $destination = print $destination "#" $url.Fragment }} 20 | {{- end }} 21 | {{- else if fileExists (print .Page.File.Dir .Destination) }} 22 | 23 | {{- else -}} 24 | {{- warnf "Page '%s' not found in '%s'" .Destination .Page.File }} 25 | {{- end }} 26 | {{- end }} 27 | {{ .Text | safeHTML }} 28 | {{- end -}} 29 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/footer.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ if and .GitInfo .Site.Params.BookRepo }} 4 |
5 | {{- $date := partial "docs/date" (dict "Date" .GitInfo.AuthorDate.Local "Format" .Site.Params.BookDateFormat) -}} 6 | {{- $commitPath := default "commit" .Site.Params.BookCommitPath -}} 7 | 8 | Calendar 9 | {{ $date }} 10 | 11 |
12 | {{ end }} 13 | 14 | {{ if and .File .Site.Params.BookRepo .Site.Params.BookEditPath }} 15 | 21 | {{ end }} 22 | 23 |
24 | 25 | {{ $script := resources.Get "clipboard.js" | resources.Minify }} 26 | {{ with $script.Content }} 27 | 28 | {{ end }} 29 | -------------------------------------------------------------------------------- /themes/book/assets/_fonts.scss: -------------------------------------------------------------------------------- 1 | /* roboto-regular - latin */ 2 | @font-face { 3 | font-family: 'Roboto'; 4 | font-style: normal; 5 | font-weight: 400; 6 | font-display: swap; 7 | src: local(''), 8 | url('fonts/roboto-v27-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 9 | url('fonts/roboto-v27-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 10 | } 11 | /* roboto-700 - latin */ 12 | @font-face { 13 | font-family: 'Roboto'; 14 | font-style: normal; 15 | font-weight: 700; 16 | font-display: swap; 17 | src: local(''), 18 | url('fonts/roboto-v27-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 19 | url('fonts/roboto-v27-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 20 | } 21 | 22 | /* roboto-mono-regular - latin */ 23 | @font-face { 24 | font-family: 'Roboto Mono'; 25 | font-style: normal; 26 | font-weight: 400; 27 | font-display: swap; 28 | src: local(''), 29 | url('fonts/roboto-mono-v13-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 30 | url('fonts/roboto-mono-v13-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 31 | } 32 | 33 | body { 34 | font-family: 'Roboto', sans-serif; 35 | } 36 | 37 | code { 38 | font-family: 'Roboto Mono', monospace; 39 | } 40 | -------------------------------------------------------------------------------- /themes/book/assets/sw.js: -------------------------------------------------------------------------------- 1 | const cacheName = self.location.pathname 2 | const pages = [ 3 | {{ if eq .Site.Params.BookServiceWorker "precache" }} 4 | {{ range .Site.AllPages -}} 5 | "{{ .RelPermalink }}", 6 | {{ end -}} 7 | {{ end }} 8 | ]; 9 | 10 | self.addEventListener("install", function (event) { 11 | self.skipWaiting(); 12 | 13 | caches.open(cacheName).then((cache) => { 14 | return cache.addAll(pages); 15 | }); 16 | }); 17 | 18 | self.addEventListener("fetch", (event) => { 19 | const request = event.request; 20 | if (request.method !== "GET") { 21 | return; 22 | } 23 | 24 | /** 25 | * @param {Response} response 26 | * @returns {Promise} 27 | */ 28 | function saveToCache(response) { 29 | if (cacheable(response)) { 30 | return caches 31 | .open(cacheName) 32 | .then((cache) => cache.put(request, response.clone())) 33 | .then(() => response); 34 | } else { 35 | return response; 36 | } 37 | } 38 | 39 | /** 40 | * @param {Error} error 41 | */ 42 | function serveFromCache(error) { 43 | return caches.open(cacheName).then((cache) => cache.match(request.url)); 44 | } 45 | 46 | /** 47 | * @param {Response} response 48 | * @returns {Boolean} 49 | */ 50 | function cacheable(response) { 51 | return response.type === "basic" && response.ok && !response.headers.has("Content-Disposition") 52 | } 53 | 54 | event.respondWith(fetch(request).then(saveToCache).catch(serveFromCache)); 55 | }); 56 | -------------------------------------------------------------------------------- /themes/book/assets/_utils.scss: -------------------------------------------------------------------------------- 1 | .flex { 2 | display: flex; 3 | } 4 | 5 | .flex-auto { 6 | flex: 1 1 auto; 7 | } 8 | 9 | .flex-even { 10 | flex: 1 1; 11 | } 12 | 13 | .flex-wrap { 14 | flex-wrap: wrap; 15 | } 16 | 17 | .justify-start { 18 | justify-content: flex-start; 19 | } 20 | 21 | .justify-end { 22 | justify-content: flex-end; 23 | } 24 | 25 | .justify-center { 26 | justify-content: center; 27 | } 28 | 29 | .justify-between { 30 | justify-content: space-between; 31 | } 32 | 33 | .align-center { 34 | align-items: center; 35 | } 36 | 37 | .mx-auto { 38 | margin: 0 auto; 39 | } 40 | 41 | .text-center { 42 | text-align: center; 43 | } 44 | 45 | .text-left { 46 | text-align: left; 47 | } 48 | 49 | .text-right { 50 | text-align: right; 51 | } 52 | 53 | .hidden { 54 | display: none; 55 | } 56 | 57 | input.toggle { 58 | height: 0; 59 | width: 0; 60 | overflow: hidden; 61 | opacity: 0; 62 | position: absolute; 63 | } 64 | 65 | .clearfix::after { 66 | content: ""; 67 | display: table; 68 | clear: both; 69 | } 70 | 71 | @mixin spin($duration) { 72 | animation: spin $duration ease infinite; 73 | @keyframes spin { 74 | 100% { 75 | transform: rotate(360deg); 76 | } 77 | } 78 | } 79 | 80 | @mixin fixed { 81 | position: fixed; 82 | top: 0; 83 | bottom: 0; 84 | overflow-x: hidden; 85 | overflow-y: auto; 86 | } 87 | 88 | @mixin outline { 89 | outline-style: auto; 90 | outline-color: currentColor; 91 | outline-color: -webkit-focus-ring-color; 92 | } 93 | -------------------------------------------------------------------------------- /themes/book/assets/_defaults.scss: -------------------------------------------------------------------------------- 1 | // Used in layout 2 | $padding-1: 1px !default; 3 | $padding-4: 0.25rem !default; 4 | $padding-8: 0.5rem !default; 5 | $padding-16: 1rem !default; 6 | 7 | $font-size-base: 16px !default; 8 | $font-size-12: 0.75rem !default; 9 | $font-size-14: 0.875rem !default; 10 | $font-size-16: 1rem !default; 11 | 12 | $border-radius: $padding-4 !default; 13 | 14 | $body-font-weight: normal !default; 15 | 16 | $body-min-width: 20rem !default; 17 | $container-max-width: 80rem !default; 18 | 19 | $header-height: 3.5rem !default; 20 | $menu-width: 14rem !default; 21 | $toc-width: 16rem !default; 22 | 23 | $mobile-breakpoint: $menu-width + $body-min-width * 1.2 + $toc-width !default; 24 | 25 | $hint-colors: ( 26 | info: #6bf, 27 | warning: #fd6, 28 | danger: #f66, 29 | ) !default; 30 | 31 | // Themes 32 | @mixin theme-light { 33 | --gray-100: #f8f9fa; 34 | --gray-200: #e9ecef; 35 | --gray-500: #adb5bd; 36 | 37 | --color-link: #0055bb; 38 | --color-visited-link: #8440f1; 39 | 40 | --body-background: white; 41 | --body-font-color: black; 42 | 43 | --icon-filter: none; 44 | 45 | --hint-color-info: #6bf; 46 | --hint-color-warning: #fd6; 47 | --hint-color-danger: #f66; 48 | } 49 | 50 | @mixin theme-dark { 51 | --gray-100: rgba(255, 255, 255, 0.1); 52 | --gray-200: rgba(255, 255, 255, 0.2); 53 | --gray-500: rgba(255, 255, 255, 0.5); 54 | 55 | --color-link: #84b2ff; 56 | --color-visited-link: #b88dff; 57 | 58 | --body-background: #343a40; 59 | --body-font-color: #e9ecef; 60 | 61 | --icon-filter: brightness(0) invert(1); 62 | 63 | --hint-color-info: #6bf; 64 | --hint-color-warning: #fd6; 65 | --hint-color-danger: #f66; 66 | } 67 | -------------------------------------------------------------------------------- /content/docs/zkdocs/template.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "A title" 5 | summary: "A summary that ends in a period." 6 | needsVariableResetButton: true 7 | draft: true 8 | references: [] 9 | --- 10 | # A title 11 | 12 | 13 | {{< hint info >}} 14 | **Goal:** 15 | $\varprover$ convinces $\varverifier$ that they know 16 | {{< /hint >}} 17 | 18 | * __Public input:__ cyclic group $\cgroup$ of prime order $\varq$ and a generator $\varg\in \cgroup$ 19 | * __Private input:__ $\varprover$ knows a secret 20 | 21 | 22 | ### Interactive protocol 23 | 24 | {{< rawhtml >}} 25 | $$ 26 | \begin{array}{c} 27 | \work{\varprover}{\varverifier} 28 | \alicework{\samplezqs{\varr}} 29 | \alicework{\varu = \varg^\varr} 30 | \alicebob{}{\varu}{} 31 | \bobwork{\sample{\varc}} 32 | \bobalice{}{\varc}{} 33 | \alicework{\varz = \varr + \varx\cdot \varc} 34 | \alicebob{}{\varz}{} 35 | \bobwork{\varg^{\varz} \equalQ \varu \cdot \varh^\varc } 36 | \end{array} 37 | $$ 38 | 39 | {{< /rawhtml >}} 40 | ----- 41 | 42 | ### Non-interactive protocol 43 | We can transform this identification scheme into a non-interactive protocol using the Fiat-Shamir heuristic, where the prover 44 | creates itself the random challenge $c$. To do this, we need to hash together *all* elements of the public set $\\{\varg, \varq, \varh\\}$ as well as the public values of the interaction. 45 | {{< rawhtml >}} 46 | $$ 47 | \begin{array}{c} 48 | \work{\varprover}{\varverifier} 49 | \alicework{\samplezqs{\varr}} 50 | \alicework{\varu = \varg^\varr} 51 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 52 | \alicework{\varz = \varr + \varx\cdot \varc} 53 | \alicebob{}{\varu, \varc, \varz}{} 54 | \bobwork{\varc \equalQ \hash{\varg, \varq, \varh, \varu}} 55 | \bobwork{\varg^\varz \equalQ \varu \cdot \varh ^\varc } 56 | \end{array} 57 | $$ 58 | {{< /rawhtml >}} 59 | 60 | 61 | 62 | ## Security assumptions 63 | 64 | 65 | ## Security pitfalls 66 | 67 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/menu-filetree.html: -------------------------------------------------------------------------------- 1 | {{ $bookSection := default "docs" .Site.Params.BookSection }} 2 | {{ if eq $bookSection "*" }} 3 | {{ $bookSection = "/" }}{{/* Backward compatibility */}} 4 | {{ end }} 5 | 6 | {{ with .Site.GetPage $bookSection }} 7 | {{ template "book-section-children" (dict "Section" . "CurrentPage" $) }} 8 | {{ end }} 9 | 10 | {{ define "book-section-children" }}{{/* (dict "Section" .Section "CurrentPage" .CurrentPage) */}} 11 |
    12 | {{ range (where .Section.Pages "Params.bookhidden" "ne" true) }} 13 | {{ if .IsSection }} 14 |
  • 15 | {{ template "book-page-link" (dict "Page" . "CurrentPage" $.CurrentPage) }} 16 | {{ template "book-section-children" (dict "Section" . "CurrentPage" $.CurrentPage) }} 17 |
  • 18 | {{ else if and .IsPage .Content }} 19 |
  • 20 | {{ template "book-page-link" (dict "Page" . "CurrentPage" $.CurrentPage) }} 21 |
  • 22 | {{ end }} 23 | {{ end }} 24 |
25 | {{ end }} 26 | 27 | {{ define "book-page-link" }}{{/* (dict "Page" .Page "CurrentPage" .CurrentPage) */}} 28 | {{ $current := eq .CurrentPage .Page }} 29 | {{ $ancestor := .Page.IsAncestor .CurrentPage }} 30 | 31 | {{ if .Page.Params.bookCollapseSection }} 32 | 33 | 38 | {{ else if .Page.Content }} 39 | 40 | {{- partial "docs/title" .Page -}} 41 | 42 | {{ else }} 43 | {{- partial "docs/title" .Page -}} 44 | {{ end }} 45 | {{ end }} 46 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/html-head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{- template "_internal/opengraph.html" . -}} 8 | 9 | {{ partial "docs/html-head-title" . }} 10 | 11 | {{- $manifest := resources.Get "manifest.json" | resources.ExecuteAsTemplate "manifest.json" . }} 12 | 13 | 14 | 15 | {{- range .Translations }} 16 | 17 | {{- end -}} 18 | 19 | 20 | {{- $styles := resources.Get "book.scss" | resources.ExecuteAsTemplate "book.scss" . | css.Sass | resources.Minify | resources.Fingerprint }} 21 | 22 | 23 | {{- if default true .Site.Params.BookSearch -}} 24 | {{- $searchJSFile := printf "%s.search.js" .Language.Lang }} 25 | {{- $searchJS := resources.Get "search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | resources.Fingerprint }} 26 | 27 | 28 | {{ end -}} 29 | 30 | {{- if .Site.Params.BookServiceWorker -}} 31 | {{- $swJS := resources.Get "sw-register.js" | resources.ExecuteAsTemplate "sw.js" . | resources.Minify | resources.Fingerprint }} 32 | 33 | {{ end -}} 34 | 35 | {{ template "_internal/google_analytics.html" . }} 36 | 37 | {{- with .OutputFormats.Get "rss" -}} 38 | {{ printf `` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} 39 | {{ end -}} 40 | 41 | {{ "" | safeHTML }} 45 | 46 | {{- define "integrity" -}} 47 | {{- if (urls.Parse .Permalink).Host -}} 48 | integrity="{{ .Data.Integrity }}" crossorigin="anonymous" 49 | {{- end -}} 50 | {{- end -}} 51 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Hugo site to Pages 2 | 3 | on: 4 | # Runs on pushes targeting the default branch 5 | push: 6 | branches: 7 | - main 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | # Default to bash 25 | defaults: 26 | run: 27 | shell: bash 28 | 29 | jobs: 30 | # Build job 31 | build: 32 | runs-on: ubuntu-latest 33 | env: 34 | HUGO_VERSION: 0.137.1 35 | steps: 36 | - name: Install Hugo CLI 37 | run: | 38 | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ 39 | && sudo dpkg -i ${{ runner.temp }}/hugo.deb 40 | - name: Install Dart Sass 41 | run: sudo snap install dart-sass 42 | - name: Checkout 43 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 44 | with: 45 | submodules: recursive 46 | fetch-depth: 0 47 | persist-credentials: false 48 | - name: Setup Pages 49 | id: pages 50 | uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 51 | - name: Install Node.js dependencies 52 | run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" 53 | - name: Build with Hugo 54 | env: 55 | HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache 56 | HUGO_ENVIRONMENT: production 57 | run: | 58 | hugo \ 59 | --gc \ 60 | --minify \ 61 | --baseURL "${{ steps.pages.outputs.base_url }}/" 62 | - name: Upload artifact 63 | uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 64 | with: 65 | path: ./public 66 | 67 | # Deployment job 68 | deploy: 69 | environment: 70 | name: github-pages 71 | url: ${{ steps.deployment.outputs.page_url }} 72 | runs-on: ubuntu-latest 73 | needs: build 74 | steps: 75 | - name: Deploy to GitHub Pages 76 | id: deployment 77 | uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 78 | -------------------------------------------------------------------------------- /content/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | type: docs 4 | --- 5 | 6 | # ZKDocs 7 | 8 | ## Zero-knowledge protocols 9 | 10 | ZKDocs provides comprehensive, detailed, and interactive documentation on zero-knowledge proof systems and related primitives. 11 | 12 | At [Trail of Bits](https://www.trailofbits.com/), we audit many implementations of non-standardized cryptographic protocols and often find the same issues. As we discovered more instances of these bugs, we wanted to find a way to prevent them in the future. Unfortunately, for these protocols, the burden is on the developers to figure out all of the low-level implementation details and security pitfalls. 13 | 14 | We hope that ZKDocs can fill in this gap and benefit the larger cryptography community. 15 | 16 | {{< columns >}} 17 | 18 | ### Comprehensive 19 | We aim to be both self-contained and comprehensive in the topics related to zero-knowledge proof systems, from descriptions of simple systems like [Schnorr’s identification protocol]({{< relref "/docs/zkdocs/zero-knowledge-protocols/schnorr" >}}), to complex proof systems like [Paillier-Blum modulus]({{< relref "/docs/zkdocs/zero-knowledge-protocols/product-primes/paillier_blum_modulus" >}}). We also cover cryptographic primitives such as: [random sampling]({{< relref "/docs/zkdocs/protocol-primitives/random-sampling" >}}), [Fiat-Shamir transformation]({{< relref "/docs/zkdocs/protocol-primitives/fiat-shamir" >}}), and [Shamir's Secret Sharing]({{< relref "/docs/zkdocs/protocol-primitives/shamir" >}}). 20 | 21 | <---> 22 | 23 | ### Detailed 24 | We describe each protocol in great detail, including all necessary setup, sanity-checks, auxiliary algorithms, further references, and potential security pitfalls with their associated severity. 25 | 26 | {{< /columns >}} 27 | 28 | 29 | ### Interactive 30 | 31 | The protocol descriptions are interactive, letting you modify variable names. This allows you to match the variable names in ZKdocs' specification to the variable names in your code, making it easier to find bugs and missing assertions. 32 | 33 | Interactivity features: 34 | - Click on $\varX$ to highlight the variable across the document. Try it! 35 | - Type or paste with $\varX$ highlighted to edit $\varX$'s name. Press `Enter` or `Escape` to stop editing. 36 | - Press the {{< rawhtml >}}{{< /rawhtml>}} button to reset the names of all variables on the current page (variable names are independent across different pages) 37 | 38 | 39 | {{< box >}} 40 | ![Basic interactivity usage](/figs/demo.gif) 41 | {{< /box >}} 42 | 43 | 44 | ### Contribute 45 | We will continue to add more proof systems like Range proofs, STARK, and Bulletproofs. 46 | 47 | Feel free to [open issues](https://github.com/trailofbits/zkdocs/issues) and suggest new protocols that you would like to see added in [ZKDocs](https://github.com/trailofbits/zkdocs). 48 | -------------------------------------------------------------------------------- /content/docs/zkdocs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "Introduction" 5 | --- 6 | 7 | # Introduction 8 | 9 | ## Zero-knowledge protocols 10 | 11 | ZKDocs provides comprehensive, detailed, and interactive documentation on zero-knowledge proof systems and related primitives. 12 | 13 | At [Trail of Bits](https://www.trailofbits.com/), we audit many implementations of non-standardized cryptographic protocols and often find the same issues. As we discovered more instances of these bugs, we wanted to find a way to prevent them in the future. Unfortunately, for these protocols, the burden is on the developers to figure out all of the low-level implementation details and security pitfalls. 14 | 15 | We hope that ZKDocs can fill in this gap and benefit the larger cryptography community. 16 | 17 | {{< columns >}} 18 | 19 | ### Comprehensive 20 | We aim to be both self-contained and comprehensive in the topics related to zero-knowledge proof systems, from descriptions of simple systems like [Schnorr’s identification protocol]({{< relref "/docs/zkdocs/zero-knowledge-protocols/schnorr" >}}), to complex proof systems like [Paillier-Blum modulus]({{< relref "/docs/zkdocs/zero-knowledge-protocols/product-primes/paillier_blum_modulus" >}}). We also cover cryptographic primitives such as: [random sampling]({{< relref "/docs/zkdocs/protocol-primitives/random-sampling" >}}), [Fiat-Shamir transformation]({{< relref "/docs/zkdocs/protocol-primitives/fiat-shamir" >}}), and [Shamir's Secret Sharing]({{< relref "/docs/zkdocs/protocol-primitives/shamir" >}}). 21 | 22 | <---> 23 | 24 | ### Detailed 25 | We describe each protocol in great detail, including all necessary setup, sanity-checks, auxiliary algorithms, further references, and potential security pitfalls with their associated severity. 26 | 27 | {{< /columns >}} 28 | 29 | 30 | ### Interactive 31 | 32 | The protocol descriptions are interactive, letting you modify variable names. This allows you to match the variable names in ZKdocs' specification to the variable names in your code, making it easier to find bugs and missing assertions. 33 | 34 | Interactivity features: 35 | - Click on $\varX$ to highlight the variable across the document. Try it! 36 | - Type or paste with $\varX$ highlighted to edit $\varX$'s name. Press `Enter` or `Escape` to stop editing. 37 | - Press the {{< rawhtml >}}{{< /rawhtml>}} button to reset the names of all variables on the current page (variable names are independent across different pages) 38 | 39 | 40 | {{< box >}} 41 | ![Basic interactivity usage](/figs/demo.gif) 42 | {{< /box >}} 43 | 44 | 45 | ### Contribute 46 | We will continue to add more proof systems like Range proofs, STARK, and Bulletproofs. 47 | 48 | Feel free to [open issues](https://github.com/trailofbits/zkdocs/issues) and suggest new protocols that you would like to see added in [ZKDocs](https://github.com/trailofbits/zkdocs). 49 | -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/nums.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 4 3 | bookFlatSection: true 4 | title: "Nothing-up-my-sleeve constructions" 5 | summary: "Generic, honest, and deterministic method to sample elements." 6 | references: ["shake"] 7 | --- 8 | # Nothing-up-my-sleeve constructions 9 | 10 | Protocols often require using public but random group elements or alternative generators. If these were simply randomly sampled, other participants could be suspicious that the party did not honestly generate them. 11 | 12 | To generate the elements you require: 13 | - **membership:** know how to check membership in the sample space 14 | - **bit-size:** know the bit-size of the elements 15 | - **binding parameters:** the protocol's public values other binding parameters like an index 16 | - **salt** 17 | 18 | {{< hint info >}} 19 | **Example:** In the [Short factoring proofs]({{< relref "/docs/zkdocs/zero-knowledge-protocols/short-factoring-proofs#non-interactive-protocol" >}}) non-interactive protocol, we need to generate values $\varz_i \in \zns{\varN}$. Our ingredients are: 20 | - **membership:** to check if an element $e$ is in $\zns{\varN}$, we check that $\gcd(e, \varN) = 1$ 21 | - **bit-size:** the element bit-size will be $|\varN|$ 22 | - **binding parameters:** $\varN$ and $i$ 23 | - **salt:** the salt can be $\mathsf{"shortfactoringproof"}$ 24 | {{< /hint >}} 25 | 26 | The construction is generic: start a counter and sample an element with an extendible-output hash function over the binding parameters and the counter; if the generated element is in the sample space, we return it; otherwise, we increment the counter and sample again. 27 | 28 | ```python 29 | DS = '|' 30 | 31 | # Rejection sampling using a counter and binding parameters of the protocol 32 | def gen_element(sample_space_predicate, bitsize, param_list, salt): 33 | counter = 0 34 | while True: 35 | 36 | # elements to hash 37 | elements = param_list + [salt, counter] 38 | 39 | # add each element's length 40 | to_hash = [len(s) + s for s in elements] 41 | 42 | # domain separated elements 43 | to_hash = DS + DS.join(to_hash) 44 | 45 | # generate bitsize element with extendible-output hash function 46 | e = hash_xof(to_hash, bitsize) 47 | 48 | # check that e is in sample_space 49 | if sample_space_predicate(e): 50 | return e 51 | 52 | # increment counter 53 | counter += 1 54 | ``` 55 | 56 | ## Hash function choice 57 | The hash function used here must be an extendible-output function (XOF). These hash functions can generate an output of arbitrary length. We must use these functions since the elements we are sampling can have an arbitrary number of bits, and failing to achieve that size can cause security issues. An example is $\mathsf{SHAKE256}$, which provides 256-bit security against collision attacks when at least 512 bits are sampled. 58 | 59 | An alternative is using $\mathsf{TupleHash}$ which does not require manually domain-separating the elements to be hashed. 60 | 61 | -------------------------------------------------------------------------------- /themes/book/assets/_shortcodes.scss: -------------------------------------------------------------------------------- 1 | .markdown { 2 | // {{< expand "Label" "icon" >}} 3 | .book-expand { 4 | margin-top: $padding-16; 5 | margin-bottom: $padding-16; 6 | 7 | border: $padding-1 solid var(--gray-200); 8 | border-radius: $border-radius; 9 | 10 | overflow: hidden; 11 | 12 | .book-expand-head { 13 | background: var(--gray-100); 14 | padding: $padding-8 $padding-16; 15 | cursor: pointer; 16 | } 17 | 18 | .book-expand-content { 19 | display: none; 20 | padding: $padding-16; 21 | } 22 | 23 | input[type="checkbox"]:checked + .book-expand-content { 24 | display: block; 25 | } 26 | } 27 | 28 | // {{< tabs >}} 29 | .book-tabs { 30 | margin-top: $padding-16; 31 | margin-bottom: $padding-16; 32 | 33 | border: $padding-1 solid var(--gray-200); 34 | border-radius: $border-radius; 35 | 36 | overflow: hidden; 37 | 38 | display: flex; 39 | flex-wrap: wrap; 40 | 41 | label { 42 | display: inline-block; 43 | padding: $padding-8 $padding-16; 44 | border-bottom: $padding-1 transparent; 45 | cursor: pointer; 46 | } 47 | 48 | .book-tabs-content { 49 | order: 999; //Move content blocks to the end 50 | width: 100%; 51 | border-top: $padding-1 solid var(--gray-100); 52 | padding: $padding-16; 53 | display: none; 54 | } 55 | 56 | input[type="radio"]:checked + label { 57 | border-bottom: $padding-1 solid var(--color-link); 58 | } 59 | input[type="radio"]:checked + label + .book-tabs-content { 60 | display: block; 61 | } 62 | input[type="radio"]:focus + label { 63 | @include outline; 64 | } 65 | } 66 | 67 | // {{< columns >}} 68 | .book-columns { 69 | margin-left: -$padding-16; 70 | margin-right: -$padding-16; 71 | 72 | > div { 73 | margin: $padding-16 0; 74 | min-width: $body-min-width / 2; 75 | padding: 0 $padding-16; 76 | } 77 | } 78 | 79 | // {{< hint >}} 80 | .book-hint { 81 | @each $name, $color in $hint-colors { 82 | &.#{$name} { 83 | border-color: $color; 84 | background-color: rgba($color, 0.1); 85 | } 86 | } 87 | } 88 | 89 | // {{< box >}} 90 | .book-box { 91 | border-color: grey; 92 | background-color: rgba(grey, 0.1); 93 | border: $padding-1 solid var(--gray-200); 94 | } 95 | } 96 | 97 | // {{< button >}} 98 | .book-btn { 99 | display: inline-block; 100 | font-size: $font-size-14; 101 | color: black; 102 | line-height: $padding-16 * 1; 103 | padding: 0 $padding-16; 104 | border: $padding-1 solid black; 105 | border-radius: $border-radius; 106 | background-color: rgba(gray, 0.4); 107 | cursor: pointer; 108 | box-shadow: 0 1px #999; 109 | outline: none; 110 | 111 | &:hover { 112 | background-color: rgba(gray, 0.2); 113 | } 114 | 115 | &:active { 116 | box-shadow: 0 0; 117 | transform: translateY(1px); 118 | } 119 | } -------------------------------------------------------------------------------- /themes/book/assets/search.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | {{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }} 4 | {{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }} 5 | {{ $searchConfig := i18n "bookSearchConfig" | default "{}" }} 6 | 7 | (function () { 8 | const searchDataURL = '{{ $searchData.RelPermalink }}'; 9 | const indexConfig = Object.assign({{ $searchConfig }}, { 10 | doc: { 11 | id: 'id', 12 | field: ['title', 'content'], 13 | store: ['title', 'href', 'section'] 14 | } 15 | }); 16 | 17 | const input = document.querySelector('#book-search-input'); 18 | const results = document.querySelector('#book-search-results'); 19 | 20 | if (!input) { 21 | return 22 | } 23 | 24 | input.addEventListener('focus', init); 25 | input.addEventListener('keyup', search); 26 | 27 | // document.addEventListener('keypress', focusSearchFieldOnKeyPress); 28 | 29 | /** 30 | * @param {Event} event 31 | */ 32 | function focusSearchFieldOnKeyPress(event) { 33 | if (input === document.activeElement) { 34 | return; 35 | } 36 | 37 | const characterPressed = String.fromCharCode(event.charCode); 38 | if (!isHotkey(characterPressed)) { 39 | return; 40 | } 41 | 42 | input.focus(); 43 | event.preventDefault(); 44 | } 45 | 46 | /** 47 | * @param {String} character 48 | * @returns {Boolean} 49 | */ 50 | function isHotkey(character) { 51 | const dataHotkeys = input.getAttribute('data-hotkeys') || ''; 52 | return dataHotkeys.indexOf(character) >= 0; 53 | } 54 | 55 | function init() { 56 | input.removeEventListener('focus', init); // init once 57 | input.required = true; 58 | 59 | fetch(searchDataURL) 60 | .then(pages => pages.json()) 61 | .then(pages => { 62 | window.bookSearchIndex = FlexSearch.create('balance', indexConfig); 63 | window.bookSearchIndex.add(pages); 64 | }) 65 | .then(() => input.required = false) 66 | .then(search); 67 | } 68 | 69 | function search() { 70 | while (results.firstChild) { 71 | results.removeChild(results.firstChild); 72 | } 73 | 74 | if (!input.value) { 75 | return; 76 | } 77 | 78 | const searchHits = window.bookSearchIndex.search(input.value, 10); 79 | searchHits.forEach(function (page) { 80 | const li = element('
  • '); 81 | const a = li.querySelector('a'), small = li.querySelector('small'); 82 | 83 | a.href = page.href; 84 | a.textContent = page.title; 85 | small.textContent = page.section; 86 | 87 | results.appendChild(li); 88 | }); 89 | } 90 | 91 | /** 92 | * @param {String} content 93 | * @returns {Node} 94 | */ 95 | function element(content) { 96 | const div = document.createElement('div'); 97 | div.innerHTML = content; 98 | return div.firstChild; 99 | } 100 | })(); 101 | -------------------------------------------------------------------------------- /static/TOB_Black.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /themes/book/static/katex/auto-render.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([function(t,r){t.exports=e},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),a=function(e,t,r){for(var n=r,o=0,a=e.length;n 2 | 3 | 4 | {{ partial "docs/html-head" . }} 5 | {{ partial "docs/inject/head" . }} 6 | 7 | 8 | 9 | 10 |
    11 | 16 | 17 |
    18 |
    19 | {{ template "header" . }} 20 |
    21 | 22 | {{ partial "docs/inject/content-before" . }} 23 | {{ template "main" . }} 24 | {{ partial "docs/inject/content-after" . }} 25 | 26 |
    27 | {{ template "footer" . }} 28 | {{ partial "docs/inject/footer" . }} 29 |
    30 | 31 | {{ template "comments" . }} 32 | 33 | 34 |
    35 | 36 | {{ if default true (default .Site.Params.BookToC .Params.BookToC) }} 37 | 49 | {{ end }} 50 |
    51 | 52 | {{ partial "docs/inject/body" . }} 53 | 54 | 55 | 56 | {{ define "menu" }} 57 | {{ partial "docs/menu" . }} 58 | {{ end }} 59 | 60 | {{ define "header" }} 61 | {{ partial "docs/header" . }} 62 | 63 | {{ if default true (default .Site.Params.BookToC .Params.BookToC) }} 64 | 67 | {{ end }} 68 | {{ end }} 69 | 70 | {{ define "footer" }} 71 | {{ partial "docs/footer" . }} 72 | {{ end }} 73 | 74 | {{ define "comments" }} 75 | {{ if and .Content (default true (default .Site.Params.BookComments .Params.BookComments)) }} 76 |
    77 | {{- partial "docs/comments" . -}} 78 |
    79 | {{ end }} 80 | {{ end }} 81 | 82 | {{ define "main" }} 83 |
    84 | {{- .Content -}} 85 | 86 | {{if .Params.references}} 87 |

    References #

    88 | {{range $ref := .Params.references}} 89 | {{ $details := index $.Site.Data.references $ref }} 90 |
      91 |
    • {{if $details.tag}}[{{$details.tag}}]{{end}} {{$details.title}}{{if $details.year }} ({{$details.year}}){{ end }}.
    • 92 |
    93 | {{end}} 94 | {{end}} 95 | 96 |
    97 | {{ end }} 98 | 99 | {{ define "toc" }} 100 | {{ partial "docs/toc" . }} 101 | {{ end }} 102 | -------------------------------------------------------------------------------- /content/docs/zkdocs/security-of-zkps/when-to-use-hvzk.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 5 3 | bookFlatSection: true 4 | title: "Using HVZKP in the wrong context" 5 | needsVariableResetButton: true 6 | summary: "Potential attacks when honest verifier zero-knowledge proofs are used in the context of a malicious verifier." 7 | references: ["hoc", "gg21"] 8 | --- 9 | ## Using HVZKP in the wrong context 10 | Honest verifier zero-knowledge proofs (HVZKP) assume --yes, you guessed it-- an honest verifier! This means that in the presence of malicious verifiers, non-interactive protocols should always be used. These also exchange fewer messages between prover and verifier. 11 | 12 | A malicious verifier can employ different attacks depending on the proof system. Here, we will present attacks for the [Short factoring proofs](../../zero-knowledge-protocols/short-factoring-proofs) and the [Two prime divisors proof](../../zero-knowledge-protocols/product-primes/two-prime-divisors). 13 | 14 | ## The case of the Short-Factoring-Proofs 15 | Recall that in [Short factoring proofs](../../zero-knowledge-protocols/short-factoring-proofs) the prover shows that they know $\varphi(\varN)$ in the style of [Girault's scheme](../../zero-knowledge-protocols/girault-identification). 16 | {{< rawhtml >}} 17 | $$ 18 | \begin{array}{c} 19 | \work{\varprover}{\varverifier} 20 | \alicework{\sampleRange{\varr}{A}} 21 | \alicework{\varx_i = \varz_i^\varr \mod \varN} 22 | \alicework{\forb} 23 | \alicebob{}{\bunch{\varx}}{} 24 | \bobwork{\sampleRange{\vare}{B}} 25 | \bobalice{}{\vare}{} 26 | \alicework{\vary = \varr + (\varN - \varphi(\varN))\cdot \vare \in \naturals} 27 | \alicebob{}{\vary}{} 28 | \bobwork{\vary \inQ \range{A}} 29 | \bobwork{\varx_i \equalQ \varz_i^{\vary- \vare\cdot\varN} \mod \varN \forb} 30 | \end{array} 31 | $$ 32 | {{< /rawhtml >}} 33 | 34 | After the initial commit, the verifier responds with a challenge $e$ supposedly sampled from $\range{B}$. However, being malicious, the verifier chooses $\vare=A$, the maximum value that $\varr$ can be. So, that after receiving $\vary = \varr + (\varN - \varphi(\varN))\cdot \vare$, they can compute $\varN - \vary//\vare$ which will reveal $\varphi(\varN)$. 35 | 36 | 37 | ## The case of the Two-Prime-Divisor proof 38 | In the [Two prime divisors proof](../../zero-knowledge-protocols/product-primes/two-prime-divisors), the prover has no way of checking if the verifier is trying to attack them. Recall the beginning of the protocol that the verifier chooses $\rhovar_i$ values: 39 | {{< rawhtml >}} 40 | $$ 41 | \begin{array}{c} 42 | \work{\varprover}{\varverifier} 43 | \bobwork{\sampleSet{\rhovar_i}{J_\varN}, \text{ for }i=1,\ldots,m} 44 | \bobalice{}{\{\rhovar_i\}_{i=1}^m}{} 45 | \alicework{\sigmavar_i = \begin{cases} 46 | \sqrt{\rhovar_i} \mod \varN &\text{ if }\rhovar_i \in QR_\varN \\ 47 | 0 &\text{ otherwise} 48 | \end{cases} 49 | } 50 | \alicework{\text{ for }i=1,\ldots,m} 51 | \alicebob{}{\{\sigmavar_i\}_{i=1}^m}{} 52 | \end{array} 53 | $$ 54 | {{< /rawhtml >}} 55 | 56 | Then, the verifier computes the square-roots of these values! It is known that factoring and computing modular square-roots are equivalent [[HOC] - Fact 3.46]. 57 | 58 | An attacker can: 59 | - select random numbers $r_i$ 60 | - send their square $r^2_i \mod \varN$ to the prover, 61 | 62 | The prover will compute their square roots, $\sigma_i$ which can be different than $\pm \varr_i$ since there are four different square-roots modulo $\varN = p q$. When $\sigma_i\neq \pm \varr_i$, computing $\gcd (\varN, \sigma_i - r_i)$ will reveal one of the factors of $\varN$. This is because 63 | 64 | $\begin{align*} 65 | \sigma_i^2 &\equiv r_i^2 \mod \varN \\\\ 66 | (\sigma_i^2 - r_i^2) &\equiv 0 \mod \varN \\\\ 67 | (\sigma_i - r_i)(\sigma_i + r_i) &\equiv 0 \mod \varN 68 | \end{align*}$ 69 | 70 | 71 | 72 | 73 | 74 | [HOC]: https://cacr.uwaterloo.ca/hac/ 75 | 76 | 77 | -------------------------------------------------------------------------------- /content/docs/zkdocs/notation.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "Notation & Definitions" 5 | summary: "Common notation and definitions used in the documentation." 6 | references: ["hoc"] 7 | --- 8 | # Notation and Definitions 9 | 10 | This page is a glossary for notation and concepts present in the documentation. 11 | 12 | ## Sets, Groups, and Special Functions 13 | - $\mathbb{Z}$ is the set of integers, $\\{\ldots, -2, -1, 0, 1, 2, \ldots\\}$. 14 | - $\naturals$ is the set of integers greater than or equal to 0, $\\{0, 1, 2, \ldots\\}$. 15 | - $\range{b}$ is the finite set of integers $\\{0, \ldots, b-1\\}$. 16 | - $\gcd(n, m)$ is the nonnegative [greatest common divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor) of integers $n$ and $m$; when $\gcd(n, m) = 1$, $n$ and $m$ are said to be *coprime*. 17 | - $\z{n}$ are the integers modulo $n$, a set associated with the equivalence classes of integers $\\{0, 1, \ldots, n-1\\}$. 18 | - $\zns{n}$ is the multiplicative group of integers modulo $n$: an element $e$ from $\z{n}$ is in $\zns{n}$ iff $\gcd(e, n) = 1$, that is $\zns{n} = \\{e \in \z{n}: \gcd(e, n) = 1\\}$. When $n$ is prime, then $\zns{n} = \\{1, \ldots, n-1\\}$. 19 | - $\field{p}$ is the finite field of order $p$; when $p$ is a prime number, these are the integers modulo $p$, $\z{p}$; when $p$ is a prime power $q^k$, these are [Galois fields](https://en.wikipedia.org/wiki/Finite_field). 20 | - $\varphi(n)$ is Euler's [totient function](https://en.wikipedia.org/wiki/Euler%27s_totient_function); for $n\geq 1$, it is the number of integers in $\\{1,\ldots, n\\}$ coprime with $n.$ 21 | - $|S|$ is the *order* of a set $S$, i.e., its number of elements. For example, $|\zns{n}| = \varphi(n)$, and for a prime $n$, $|\zns{n}| = n-1$. 22 | 23 | ## Vectors 24 | - $\vec{a} \in \z{q}^n$ is a vector $(a_1,\dots,a_n)$ with $a_i \in \z{q}$ for all $i$. 25 | - $c \cdot \vec{a}$ denotes the scalar product $(c \cdot a_1,\dots,c \cdot a_n)$. 26 | - $\ip{\vec{a}}{\vec{b}}$ denotes the inner product $\sum_{i=1}^n a_i \cdot b_i$. 27 | 28 | ## Number-theory 29 | - $J(w, n)\in \\{-1, 0, 1\\}$ is the [Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol) of $w$ modulo $n$, only defined for positive and odd $n$. 30 | - $J_n$ is the set of elements of $\zns{n}$ with Jacobi symbol $1$. 31 | - $QR_n$ is the set of quadratic residues modulo $n$, which are elements that have a square-root, i.e., $QR_n = \\{e \in \z{n} : \exists r . r^2 = e \mod n\\}$. 32 | 33 | ## Sampling 34 | In protocol specifications, we will often need to uniformly sample elements from sets. We will use the following notation: 35 | - $\sampleGeneric{x}{X}$, where $x$ is uniformly sampled from the set $X$. 36 | 37 | Consider reading the section on [Random Sampling]({{< relref "/docs/zkdocs/protocol-primitives/random-sampling" >}}) to learn how to correctly sample a number uniformly using rejection sampling, avoiding the modulo-bias issue. 38 | 39 | ## Assertions 40 | We will use assertions in protocol descriptions. When the assertions do not hold, the protocol must abort to avoid leaking secret information. 41 | - $a \equalQ b$, requires $a=b$, and aborts otherwise 42 | - $a \gQ b$, requires $a>b$, and aborts otherwise 43 | - $a \inQ S$, requires that $a$ is in the set $S$, and aborts otherwise. 44 | 45 | ## Implementations of number-theoretic algorithms 46 | In general, we highly recommend the [Handbook of Applied Cryptography](https://cacr.uwaterloo.ca/hac/), which has detailed descriptions of most algorithms. 47 | 48 | ## Hash Functions 49 | - $\hash{\cdot}$ is a cryptographically secure domain-separated hash function. 50 | - $\hashbit{\cdot}{k}$ is a cryptographically secure domain-separated hash function with specific output-size of $k$-bits. 51 | 52 | Find more details on the particular hash functions in [Nothing-up-my-sleeve constructions]({{< relref "/docs/zkdocs/protocol-primitives/nums#hash-function-choice" >}}) 53 | -------------------------------------------------------------------------------- /themes/book/assets/_markdown.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | .markdown { 4 | line-height: 1.6; 5 | 6 | // remove padding at the beginning of page 7 | > :first-child { 8 | margin-top: 0; 9 | } 10 | 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6 { 17 | font-weight: normal; 18 | line-height: 1; 19 | margin-top: 1.5em; 20 | margin-bottom: $padding-16; 21 | 22 | a.anchor { 23 | opacity: 0; 24 | font-size: 0.75em; 25 | vertical-align: middle; 26 | text-decoration: none; 27 | } 28 | 29 | &:hover a.anchor, 30 | a.anchor:focus { 31 | opacity: initial; 32 | } 33 | } 34 | 35 | h4, 36 | h5, 37 | h6 { 38 | font-weight: bolder; 39 | } 40 | 41 | h5 { 42 | font-size: 0.875em; 43 | } 44 | 45 | h6 { 46 | font-size: 0.75em; 47 | } 48 | 49 | b, 50 | optgroup, 51 | strong { 52 | font-weight: bolder; 53 | } 54 | 55 | a { 56 | text-decoration: none; 57 | 58 | &:hover { 59 | text-decoration: underline; 60 | } 61 | &:visited { 62 | color: var(--color-visited-link); 63 | } 64 | } 65 | 66 | img { 67 | max-width: 100%; 68 | height: auto; 69 | } 70 | 71 | code { 72 | padding: 0 $padding-4; 73 | background: var(--gray-200); 74 | border-radius: $border-radius; 75 | font-size: 0.875em; 76 | } 77 | 78 | pre { 79 | padding: $padding-16; 80 | background: var(--gray-100); 81 | border-radius: $border-radius; 82 | overflow-x: auto; 83 | 84 | code { 85 | padding: 0; 86 | background: none; 87 | } 88 | } 89 | 90 | blockquote { 91 | margin: $padding-16 0; 92 | padding: $padding-8 $padding-16 $padding-8 ($padding-16 - $padding-4); //to keep total left space 16dp 93 | 94 | border-inline-start: $padding-4 solid var(--gray-200); 95 | border-radius: $border-radius; 96 | 97 | :first-child { 98 | margin-top: 0; 99 | } 100 | :last-child { 101 | margin-bottom: 0; 102 | } 103 | } 104 | 105 | table { 106 | overflow: auto; 107 | display: block; 108 | border-spacing: 0; 109 | border-collapse: collapse; 110 | margin-top: $padding-16; 111 | margin-bottom: $padding-16; 112 | 113 | tr th, 114 | tr td { 115 | padding: $padding-8 $padding-16; 116 | border: $padding-1 solid var(--gray-200); 117 | } 118 | 119 | tr:nth-child(2n) { 120 | background: var(--gray-100); 121 | } 122 | } 123 | 124 | hr { 125 | height: $padding-1; 126 | border: none; 127 | background: var(--gray-200); 128 | } 129 | 130 | ul, 131 | ol { 132 | padding-inline-start: $padding-16 * 2; 133 | } 134 | 135 | dl { 136 | dt { 137 | font-weight: bolder; 138 | margin-top: $padding-16; 139 | } 140 | 141 | dd { 142 | margin-inline-start: 0; 143 | margin-bottom: $padding-16; 144 | } 145 | } 146 | 147 | // Special case for highlighted code with line numbers 148 | .highlight table tr { 149 | td:nth-child(1) pre { 150 | margin: 0; 151 | padding-inline-end: 0; 152 | } 153 | td:nth-child(2) pre { 154 | margin: 0; 155 | padding-inline-start: 0; 156 | } 157 | } 158 | 159 | details { 160 | padding: $padding-16; 161 | border: $padding-1 solid var(--gray-200); 162 | border-radius: $border-radius; 163 | 164 | summary { 165 | line-height: 1; 166 | padding: $padding-16; 167 | margin: -$padding-16; 168 | cursor: pointer; 169 | } 170 | 171 | &[open] summary { 172 | margin-bottom: 0; 173 | } 174 | } 175 | 176 | figure { 177 | margin: $padding-16 0; 178 | figcaption p { 179 | margin-top: 0; 180 | } 181 | } 182 | } 183 | 184 | .markdown-inner { 185 | // Util class to remove extra margin in nested markdown content 186 | > :first-child { 187 | margin-top: 0; 188 | } 189 | > :last-child { 190 | margin-bottom: 0; 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/verifiable-secret-sharing.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 10 3 | bookFlatSection: true 4 | title: "Feldman's Verifiable Secret Sharing" 5 | summary: "A verifiable version of Shamir's secret sharing scheme due to Feldman." 6 | references: ["shamir", "feldman", "craige"] 7 | --- 8 | # Feldman's Verifiable Secret Sharing 9 | 10 | As Feldman first introduced, Verifiable secret sharing is an extension to Shamir's secret sharing scheme. The idea is that, when generating shares of the secret $S$, the splitting party also generates a set of public values that shareholders can use to validate their shares. 11 | 12 | For simplicity, we will use "Sherry" to refer to the party generating the shares of a secret $S$. We denote a share using a lower-case $s$, and a shareholder (or player) as $P$. We will assume a $\left(k, n\right)$ threshold scheme, meaning that $k$ shares are enough to recover $S$ and fewer do not obtain any information about $S$. In some protocols, the players may perform the reconstruction, independently or collaboratively. 13 | 14 | ## Share Generation and Verification 15 | 16 | ### Share Generation 17 | 18 | In standard Shamir secret sharing, Sherry generates a polynomial $$ f \left( x\right) = a_{0} + a_{1} x + \cdots + a_{k-1} x^{k-1} \in \mathbb{F}\left[x\right] \enspace ,$$ where $a_{0}=S$ and $\mathbb{F}$ is a finite field of characteristic $p$, where $p$ is a suitably large prime. Shares are generated as $s_{i}=\left(x_{i},f\left(x_{i}\right)\right)$ for $i=1,\ldots,n$. Sherry then sends $s_{i}$ to $P_{i}$ over a secure channel. Shares are generated the same way in Feldman's scheme. 19 | 20 | Feldman's scheme extends Shamir's scheme by having Sherry extend the shares to include verification values, as well as _publicly share_ an additional set of values that each player $P_{i}$ can use to verify that their share $s_{i}$ is valid. 21 | 22 | The public values are generated by translating them into elements of a commutative group $G$ for which the discrete logarithm problem is hard. For expository purposes, we'll start with $\z{q}$, the multiplicative group of integers modulo a large prime $q$, where $q-1$ is divisible by a large prime $r$, and a generator value $g\in\z{q}$ such that $\left|g\right|=r$. 23 | 24 | ### Verification Values 25 | 26 | Let $A_{j}=g^{a_{j}}\pmod{q}$ for $j=0,\ldots,k-1$. These are the verification values, and Sherry publishes all of them on a public broadcast channel. 27 | 28 | Recovering any $a_{j}$ values from the corresponding $A_{j}$ would require solving a discrete logarithm problem over $\z{q}$, which is presumed to be hard. Note that $A_{0}=g^{a_{0}}=g^{S}\pmod{q}$; solving the discrete log for $A_{0}$ would recover $S$ directly. 29 | 30 | ### Verification of Shares 31 | 32 | To verify their share $s_{i}=\left(x_{i},f\left(x_{i}\right)\right)$, player $P_{i}$ computes: 33 | 34 | $$ 35 | V_{i}=\prod_{j=0}^{k-1}{A_{j}^{x_{i}^{j}}} \enspace . 36 | $$ 37 | 38 | For each $j$, we have $A_{j}=\left(g^{a_{j}}\right)^{x_{i}^{j}}=g^{a_{j}\cdot x_{i}^{j}}$, which means 39 | 40 | $$ 41 | V_{i}=g^{a_{0}} g^{a_{1}\cdot x_{i}} g^{a_{2}\cdot x_{i}^{2}}\cdots g^{a_{k-1}\cdot x_{i}^{k-1}}=g^{a_{0} + a_{1}\cdot x_{i} + \cdots + a_{k-1}\cdot x_{i}^{k-1}}=g^{f\left(x_{i}\right)} 42 | $$ 43 | 44 | Since $P_{i}$ knows $f\left(x_{i}\right)$ as part of their share, they can compute $V_{i}'=g^{f\left(x_{i}\right)}$ directly from the value of $f\left(x_{i}\right)$ given in $s_{i}$. If $V_{i}'=V_{i}$, then $P_{i}$ accepts $s_{i}$ as valid; otherwise, they reject $s_{i}$. 45 | 46 | ## Variations 47 | 48 | Feldman points out that it is not necessary to use $\z{q}$ for generating the verification values. The paper discusses using elliptic curves over finite fields. Using the more familiar point multiplication notation for an elliptic curve group $G$ with a generator point $P\in G$, we have $V_{i}=\left[a_{0}\right]P+\left[a_{1}x_{i}\right]P+\cdots +\left[a_{k-1}x_{i}^{k-1}\right]P=Y_{i}$. 49 | 50 | ## Security pitfalls 51 | 52 | - **Forgery attack:** Craige describes a [forgery attack](https://www.jcraige.com/vss-forgery) against Feldman's technique when broadcast channels are incorrectly implemented. If an attacker can change each player's view of a single $A_{j}$ value, then it is possible to forge invalid shares for each player that will pass the verification step. 53 | - **Zero share attacks:** All of the pitfalls of Shamir's secret sharing scheme (e.g., generation of zero shares) still apply. 54 | - **Improper parameter choice:** The $p$, $q$, and $g$ values should be selected with care. While Shamir's original paper suggested using $p=2^{16}-15=65521$, this will limit the coefficients to 16 bits; recovering the $a_{j}$ values from their corresponding $A_{j}$ values becomes trivial. Further, improper selection of $q$ or $g$ can lead to several discrete log attacks. 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZKDocs 2 | ZKDocs provides comprehensive, detailed, and interactive documentation on zero-knowledge proof systems and related primitives. 3 | 4 | At [Trail of Bits](https://www.trailofbits.com/), we audit many implementations of non-standardized cryptographic protocols and often find the same issues. As we discovered more instances of these bugs, we wanted to find a way to prevent them in the future. Unfortunately, for these protocols, the burden is on the developers to figure out all of the low-level implementation details and security pitfalls. 5 | 6 | We hope that ZKDocs can fill in this gap and benefit the larger cryptography community. 7 | 8 | ### Comprehensive 9 | We aim to be both self-contained and comprehensive in the topics related to zero-knowledge proof systems, from descriptions of simple systems like Schnorr’s identification protocol, to complex proof systems like Paillier-Blum modulus. We also cover cryptographic primitives such as: random sampling, Fiat-Shamir transformation, and Shamir's Secret Sharing. 10 | 11 | 12 | ### Detailed 13 | We describe each protocol in great detail, including all necessary setup, sanity-checks, auxiliary algorithms, further references, and potential security pitfalls with their associated severity. 14 | 15 | 16 | ### Interactive 17 | 18 | The protocol descriptions are interactive, letting you modify variable names. This allows you to match the variable names in ZKdocs' specification to the variable names in your code, making it easier to find bugs and missing assertions. 19 | 20 | ![Basic interactivity usage](/static/figs/demo.gif) 21 | 22 | Interactivity features: 23 | - Click on a variable to highlight it across the document. 24 | - Type or paste with a variable highlighted to edit its name. Press `Enter` or `Escape` to stop editing. 25 | - Press the `Reset variable names` button to reset the names of all variables on the current page (variable names are independent across different pages) 26 | 27 | ---- 28 | 29 | ## Roadmap 30 | 31 | ### Zero-knowledge proof systems 32 | - [x] Schnorr basic identification protocol 33 | - [x] Schnorr variants 34 | - [x] Product of primes 35 | - [x] Square-free zkp 36 | - [x] Short proofs for factoring 37 | - [x] Girault's identification 38 | - [x] Paillier-Blum Modulus ZK 39 | - [ ] Discrete log equality 40 | - [ ] Ring-Pedersen Parameters ZK 41 | - [ ] STARK 42 | - [ ] Paillier range proofs 43 | - [ ] Bulletproofs 44 | - [ ] Sonic 45 | - [ ] Plonk 46 | 47 | ### Primitives 48 | - [x] Fiat-Shamir transformation 49 | - [x] Rejection sampling 50 | - [x] Nothing-up-my-sleeve constructions 51 | - [x] Shamir secret sharing 52 | - [x] Feldman's VSS 53 | - [ ] Fujisaki-Okamoto commitments 54 | - [ ] Pedersen commitments 55 | - [ ] HVZK and NIZK 56 | 57 | ### Common attacks and issues 58 | - [x] Using HVZKP in the wrong context: two attacks when verifiers are not so honest 59 | - [ ] Golden-shoe attack 60 | - [ ] Alpha-rays: attacking others by having short keys 61 | - [ ] Replay attacks on ZKPs 62 | 63 | ---- 64 | 65 | 66 | ## Dependencies 67 | - [hugo](https://gohugo.io/documentation/) - install with 68 | 69 | `brew install hugo` 70 | 71 | ## Running locally 72 | - `hugo server --minify --theme book` 73 | 74 | ## How to contribute 75 | - The file [schnorr.md](/content/docs/zkdocs/zero-knowledge-protocols/schnorr.md) is an example of a complete protocol. 76 | - [interactive_variables.js](static/js/interactive_variables.js) has all the variable renaming logic. 77 | - The Sigma protocols are structured in latex in 3 columns: Alice column, arrow_column, Verifier column. To write the protocols, you can use helpful latex macros: 78 | - `\work{Work for Alice}{Work for Bob}` - writes work in both Alice's and Bob's column 79 | - `\alicework{Work for Alice}`, `\bobwork{Work for Bob}` - writes work for either Alice or Bob 80 | - `\alicebob{Alice work}{message description}{Bob work}`, `\bobalice{Alice work}{message description}{Bob work}` - writes an arrow from alice to bob, or from bob to alice 81 | - In markdown you would write 82 | ```latex 83 | {{< rawhtml >}} 84 | $$ 85 | \begin{array}{c} 86 | \work{\varprover}{\varverifier} 87 | \alicework{\samplezqs{\varr}} 88 | \alicework{\varu = \varg^\varr} 89 | \alicebob{}{\varu}{} 90 | \bobwork{\sample{\varc}} 91 | \bobalice{}{\varc}{} 92 | \alicework{\varz = \varr + \varx\cdot \varc} 93 | \alicebob{}{\varz}{} 94 | \bobwork{\varg^{\varz} \equalQ \varu \cdot \varh^\varc } 95 | \end{array} 96 | $$ 97 | {{< /rawhtml >}} 98 | ``` 99 | - [header.html](themes/book/layouts/partials/docs/header.html) has all latex macros if more need to be added. In particular it includes all interactive variable macros that the javascript handles afterwards. So, if you write `$\varz$` it will default to a `z` but the user can change its name anywhere on the page. 100 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/girault-identification.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 5 3 | bookFlatSection: true 4 | title: "Girault's identification protocol" 5 | summary: "A statistical zero-knowledge proof for discrete-logarithm in a composite modulo." 6 | needsVariableResetButton: true 7 | references: ["girault", "giraultref"] 8 | --- 9 | # Girault's identification protocol 10 | This scheme is a zero-knowledge proof for a discrete logarithm, like [Schnorr's]({{< ref "schnorr.md" >}}) [protocol]({{< ref "schnorr-variants.md" >}}), but over a composite modulus instead of a prime modulus. 11 | 12 | 13 | {{< hint info >}} 14 | **Goal:** 15 | $\varprover$ convinces $\varverifier$ that they know $\varx$ such that $\varh = \varg^{-\varx} \mod \varN$ 16 | {{< /hint >}} 17 | 18 | * __Public input:__ $\varh, \varN$ and a high order generator $\varg\in \zns{\varN}$ 19 | * __Private input:__ $\varprover$ knows the secret $\varx\in \range{S}$ 20 | * __Security parameters:__ The parameters $k, k', S$ and $R = 2^{k+k' + |S|}$. 21 | 22 | ### Interactive protocol 23 | {{< hint danger >}} 24 | **Security note:** 25 | The interactive identification protocol assumes an honest verifier and should not be used in the context of malicious verifiers. A malicious verifier can send $\vare = R$ and recover the secret $\varx$ by dividing $\varz$ by $\vare$. 26 | {{< /hint >}} 27 | 28 | {{< rawhtml >}} 29 | $$ 30 | \begin{array}{c} 31 | \work{\varprover}{\varverifier} 32 | \alicework{\varh = \varg^{-\varx} \mod \varN} 33 | \alicework{\sampleRange{\varr}{R}} 34 | \alicework{\varu = \varg^\varr \mod \varN} 35 | \alicebob{}{\varu}{} 36 | \bobwork{\sampleRange{\vare}{2^k}} 37 | \bobalice{}{\vare}{} 38 | \alicework{\varz = \varr + \varx\cdot \vare \in \naturals} 39 | \alicebob{}{\varz}{} 40 | \bobwork{\varu \neq 0 \mod \varN} 41 | \bobwork{\varh \neq 0 \mod \varN} 42 | \bobwork{\varz \neq 0 \mod \varN} 43 | \bobseparator 44 | \bobwork{\varu \equalQ \varg^{\varz} \cdot \varh^\vare \mod \varN} 45 | \end{array} 46 | $$ 47 | 48 | {{< /rawhtml >}} 49 | 50 | ----- 51 | 52 | ### Non-interactive protocol 53 | We obtain a non-interactive protocol using the Fiat-Shamir heuristic, where the prover 54 | creates the random $k$-bit challenge $\vare$ using domain-separated hash function over the $\\{\varg, \varN, \varh, \varu\\}$ parameters. 55 | {{< rawhtml >}} 56 | $$ 57 | \begin{array}{c} 58 | \work{\varprover}{\varverifier} 59 | \alicework{\varh = \varg^{-\varx} \mod \varN} 60 | \alicework{\sampleRange{\varr}{R}} 61 | \alicework{\varu = \varg^\varr \mod \varN} 62 | \alicework{\vare = \hashbit{\varg, \varN, \varh, \varu}{k}} 63 | \alicework{\varz = \varr + \varx\cdot \vare \in \naturals} 64 | \alicebob{}{\varu, \vare, \varz}{} 65 | \bobwork{\varu \neq 0 \mod \varN} 66 | \bobwork{\varh \neq 0 \mod \varN} 67 | \bobwork{\varz \neq 0 \mod \varN} 68 | \bobseparator 69 | \bobwork{\vare \equalQ \hashbit{\varg, \varN, \varh, \varu}{k}} 70 | \bobwork{\varu \equalQ \varg^{\varz} \cdot \varh^\vare \mod \varN} 71 | \end{array} 72 | $$ 73 | {{< /rawhtml >}} 74 | 75 | ## Security pitfalls 76 | * **Verifier input validation:** Each of the items above the dotted line for the $\varverifier$ is essential to the security of the protocol. If any of these checks are missing or insufficient it is likely a severe security issue. 77 | * **Parameter choice:** Implementers must pay special attention to the choice of parameter values, in particular the relation between $2^k$ and $R$. If these were of similar size, since $\varz$ is computed over the naturals, $\varx$ would be approximately $\lfloor \varz/\vare\rfloor$. 78 | * __Using the interactive protocol in a malicious verifier context:__ high severity issue which allows recovering the secret $\varx$; see [Using HVZKP in the wrong context]({{< relref "/docs/zkdocs/security-of-zkps/when-to-use-hvzk" >}}). 79 | * __Verifier trusting prover on the non-interactive protocol:__ 80 | * $\varverifier$ uses a $\varg$ value provided by $\varprover$ instead of using the standard generator: this is a high severity issue since the prover can trivially forge proofs (e.g., by sending $\varu=0, \varg=0$). 81 | * $\varverifier$ does not validate $\varu,\varh$ as valid elements of $\zns{\varN}$ (between 1 and $\varN-1$ and with $\gcd(k, \varN) = 1$): this allows replaying the *same* proof with *different* values adding multiples of $\varN$. 82 | * __Replay attacks:__ After a non-interactive proof is public, it will always be valid, and anyone could pretend to know how to prove the original statement. To prevent this, consider adding additional information to the computation of the hash function: values such as an ID unique to the prover and verifier, and a timestamp. The verifier must use these values and check their validity to verify the proof. 83 | 84 | 85 | ## Choice of parameter values 86 | - $|\varN| = 2048$ 87 | - $S = 2^{256}$ 88 | - $k,k' = 128$ 89 | 90 | ## Auxiliary procedures 91 | - * __Hash function $\hashbit{\cdot}{k}$:__ this hash function should be domain-separated and have a specific output size of $k$-bits. Using $\mathsf{TupleHash}$ satisfies these restrictions. 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /content/docs/zkdocs/commitments/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 9 3 | bookFlatSection: true 4 | title: "Commitment Schemes" 5 | summary: "An overview of the commitment schemes and their applications" 6 | references: ["Blum81"] 7 | --- 8 | 9 | # Commitment Schemes Generally 10 | 11 | Commitment schemes were introduced by Blum in 1981. Blum posed the following problem: 12 | 13 | > Alice and Bob want to flip a coin by telephone. (They have just divorced, live in different cities, want to decide who gets the car.) Bob would not like to tell Alice HEADS and hear Alice (at the other end of the line) say "Here goes... I'm flipping the coin.... You lost!" 14 | 15 | Blum's solution was a _commitment scheme_: a way for Bob to send his call of HEADS or TAILS ahead of time, but in a way that makes it impossible to change his mind later, and not to _reveal_ his choice until Alice has flipped the coin. Once Alice has flipped the coin, Bob can reveal his call to Alice to see who won the coin toss. 16 | 17 | A commitment scheme has two phases: 18 | 19 | - A _commit_ phase, in which the committer generates the commitment value and shares it with others, and 20 | 21 | - An _open_ phase, when the committer reveals the committed value, and the commitment is verified by others 22 | 23 | It's very important that Bob can't cheat Alice by revealing a fake call. It's also very important that Alice can't gain any information about Bob's call from his commitment. These are the two major features of a good commitment scheme: 24 | 25 | - _Hiding_: a commitment doesn't reveal anything about the committed value 26 | 27 | - _Binding_: it is not feasible to find two or more distinct values with the same commitment 28 | 29 | Informally, you can think of hiding as what keeps Alice from cheating (since she can't get any information about Bob's call to use against him), and binding as what keeps Bob from cheating (since he can't "change his mind" and send a valid opening for $call'\neq call$ if Alice announces a coin toss result he doesn't like). 30 | 31 | Lots of cryptographic protocols rely on this sort of exchange. For instance, this type of behavior is used in threshold signature schemes to allow a group of parties to securely generate an unbiased, uniformly random signing key. 32 | 33 | To see an example of how this might be done using cryptography, consider the following process. Bob randomly selects $\sampleGeneric{call}{\{\coinheads,\cointails\}}$ as his call. Then he selects a 256-bit random value $r$ and computes, $c=\hmac{r}{call}$, then sends $c$ to Alice. Alice flips her coin, and announces either $\coinheads$ or $\cointails$. Bob then sends Alice $\left(r,call\right)$. Alice verifies that $c=\hmac{r}{call}$. If the two match, she accepts Bob's call as valid; otherwise, she rejects Bob's call as invalid. 34 | 35 | We call $c$ Bob's _commitment_ to his call, and we call $\left(r,call\right)$ the _opening_ of $c$. 36 | 37 | In protocol terms, we have: 38 | 39 | {{< rawhtml >}} 40 | $$ 41 | \begin{array}{c} 42 | \work{\varalice}{\varbob} 43 | \bobwork{\sampleGeneric{call}{\{\coinheads, \cointails\}}} 44 | \bobwork{\sampleGeneric{r}{\{0, 1\}^{256}}} 45 | \bobwork{c_{A}=\hmac{r}{call}} 46 | \bobalice{}{c_{A}}{} 47 | \alicework{\sampleGeneric{toss}{\{\coinheads, \cointails\}}} 48 | \alicebob{}{toss}{} 49 | \bobalice{}{\left(call,r\right)}{} 50 | \alicework{\hmac{r}{call}\equalQ c_{A} } 51 | \end{array} 52 | $$ 53 | {{< /rawhtml >}} 54 | 55 | It's worth noting that simply setting $C=\hash{call}$ is problematic as a commitment mechanism. In our example, it would be trivial for Alice to compute $c_{\coinheads}=\hash{\coinheads}$ and $c_{\cointails}=\hash{\cointails}$ and compare them to Bob's value for $C$. 56 | 57 | Similarly, in our $\mathsf{HMAC}$ scheme, if Bob doesn't select a fresh $r$ for each commitment, Alice can detect when Bob commits to the same value in different contexts. 58 | 59 | Of course, the $\mathsf{HMAC}$ scheme isn't limited to simple $\coinheads/\cointails$ calls; it can be used for an arbitrary message $m$: $c=\hmac{r}{m}$. 60 | 61 | This scheme will be both _hiding_ and _binding_ due to the properties of the $\mathsf{HMAC}$ function. Without $r$, Alice has no way of checking if $c$ commits to $\coinheads$ or $\cointails$, and it's computationally infeasible for Bob to find $r'$ such that $c=\hmac{r'}{call'}$ (where $call'\neq call$). 62 | 63 | It's possible to create a commitment scheme that is hiding but not binding. Suppose the commitment $c\_{A}$ above only included the lowest 16 bits of the HMAC output. It would take a fraction of a second for Bob to find $r'\neq r$ such that $c=\hmac{r'}{call'}$. 64 | 65 | Conversely, it's possible to have a commitment scheme that is binding but not hiding. The easiest example would be for Bob to simply send $call$ to Alice, as in the original, insecure coin flip protocol. Bob can't change his mind after sending $c$, but nothing is hidden from Alice. 66 | 67 | Some specialized commitment schemes provide features beyond simple binding and hiding. The KZG polynomial commitment scheme, for instance, enables Bob to commit to a polynomial $f$ while allowing him to prove that a pair $\left(x, y=f\left(x\right)\right)$ represents a correct evaluation of $f$. 68 | 69 | {{
    }} 70 | -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/alt-shamir.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 12 3 | bookFlatSection: true 4 | title: "Alternative versions of Shamir's Secret Sharing scheme" 5 | summary: "Secret sharing alternatives which do not hide the secret in the constant term of the polynomial." 6 | --- 7 | # Alternative Secret Sharing Solutions 8 | 9 | There are multiple ways to prevent inadvertently sharing the secret value by evaluating the polynomial at zero. In [Shamir Secret Sharing](../shamir), we described defense strategies to solve that problem in classical Shamir's Secret Sharing scheme. Here, we describe alternative implementations of Shamir's scheme, which ensure that evaluating $f\left(0\right)$ does not reveal $S$. 10 | 11 | {{}} 12 | These alternative schemes are certainly harder to implement (and to review), and their added complexity might not be worth the ability to mistakenly leak $f(0)$, since they can still leak the secret value by leaking other points of the polynomial. 13 | {{}} 14 | 15 | ### Transforming the Inputs Using a Nonzero Function 16 | 17 | Suppose we are working over $\z{p}$, where $p=2^{255}-19$. Consider the multiplicative group $\zns{p}$ of integers less than $p$ and relatively prime to $p$. We can define $h\left(m\right)=2^{m}\pmod{p}$. Since $0\not\in \zns{p}$, we know that $h\left(m\right)\neq 0$ for any integer $m$. Since $2$ is a generator of $\zns{p}$, we know that $h\left(m\right)$ has maximal order in $\zns{p}$. 18 | 19 | During share generation, given an integer input $x$, define $x'=h\left(x\right)$. Then, generate the corresponding share according to $\left(x',f\left(x'\right)\right)$. Because $x'\neq 0$, counters and external inputs can be used without the risk of generating a zero share. 20 | 21 | This technique is compatible with the secret reconstruction using Lagrange interpolation: as far as the Lagrange interpolating polynomial goes, a share formed from the transformed values works the same as any other shares. 22 | 23 | ### Avoiding the $y$-intercept 24 | 25 | It is possible to encode the secret $S$ into a polynomial such that $f\left(t\right)=S$ for a value $t\neq 0$. The process is only a little more complicated than the standard Shamir scheme: 26 | 27 | - Select a non-zero $t\in\field{p}$ 28 | - Select a random degree-$(k-1)$ polynomial $g\left(x\right)\in\field{p}\left[x\right]$ 29 | - Compute $S'=S-g\left(t\right)$ 30 | - Set the final polynomial to $f\left(x\right)=g\left(x\right)+S'$ 31 | 32 | We now have $f\left(t\right)=g\left(t\right)+S'=g\left(t\right)+S-g\left(t\right)=S$. The Lagrange interpolating polynomial can compute $f\left(x\right)$ at $x=t$ just as easily as at $x=0$. 33 | 34 | If shares are generated sequentially, selecting a value of $t$ larger than any reasonable number of shares $n$ (e.g., $t\gg 2^{64}$) can prevent creating an insecure share of the form $\left(t,f\left(t\right)\right)$. 35 | 36 | If shares are generated randomly, it's still possible to wind up with an insecure share by randomly selecting $t$. However, generating this value at random is significantly less likely than accidentally "generating" a zero share from a blocked read. 37 | 38 | ### Moving Away from the Constant Term 39 | 40 | There is no requirement that $S$ be encoded into $f\left(x\right)$ through the manipulation of the constant coefficient. It's possible to encode $S$ into, say, the linear coefficient of $f\left(x\right)$. Recovering the linear coefficient is straightforward, once you realize that the linear term of $f\left(x\right)$ is the constant term of $f'\left(x \right)$, the derivative of $f\left(x\right)$. 41 | 42 | The process for generating a polynomial becomes: 43 | 44 | - Generate a random, degree-$(k-3)$ polynomial $g\left(x\right)$ 45 | - Select a random $c\in\field{p}$ 46 | - Set $f\left(x\right)=g\left(x\right)x^2+Sx+c$ 47 | 48 | The Lagrange interpolating polynomial can be adapted to evaluate derivatives of polynomials; the equation used to compute the first derivative is below. The equation is slightly more complicated than before but certainly within the capability of a good programmer. 49 | 50 | $$f'\left(t\right)=\displaystyle\sum_{j=1}^{k}{y_{j}\left(\displaystyle\sum_{\begin{smallmatrix}i=1\\\\ i\neq j\end{smallmatrix}}^{k}{\left[\frac{1}{x_{j}-x_{i}}\displaystyle\prod_{\begin{smallmatrix}m=1\\\\ m\neq i,j\end{smallmatrix}}^{k}{\frac{t-x_{m}}{x_{j}-x_{m}}}\right]}\right)}$$ 51 | 52 | Evaluating $f'\left(0\right)$ gives the linear coefficient of $f\left(x\right)$, recovering $S$. 53 | 54 | ### Requiring Recovery of the Full Polynomial 55 | 56 | Finally, it's possible to encode the secret across _all_ coefficients of $f\left(x\right)$. Take $g\left(x\right)=\displaystyle\sum_{i=0}^{k-1}{a_{i}x^{i}}$ , where each $a_{i}$ is chosen uniformly at random (except that $a_{k-1}\neq 0$), then we can set $M=\displaystyle\sum_{i=0}^{k-1}{a_{i}}$ and $R=S - M$. We then select a random $0\leq i\leq k-1$ and set $f\left(x\right)=g\left(x\right)+Rx^i$. Then the sum of the coefficients is equal to $S$. 57 | 58 | Going back to the original Lagrange interpolating polynomial equation, if $t$ is replaced with a symbol $x$, the Lagrange interpolating polynomial recovers $f\left(x\right)$ exactly. $S$ can then be recovered from the reconstructed polynomial. Symbolic computations are more expensive and slightly more complex, but for, say, $k<30$, the algorithm works just fine. 59 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/schnorr-variants.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "Variants of Schnorr's identification protocol" 5 | summary: "Common variants of Schnorr's protocol." 6 | needsVariableResetButton: true 7 | references: ["schnorr_rfc"] 8 | --- 9 | # Variants of Schnorr's identification protocol 10 | All variants of Schnorr's protocol prove the knowledge of an $\varx$ such that $\varh = \varg^\varx$ for a public $\varh$. 11 | 12 | The differences are tradeoffs between the size of the proof statements and a more costly proof verification, and smaller communication overhead. 13 | 14 | {{< hint info >}} 15 | **Goal:** 16 | $\varprover$ convinces $\varverifier$ that they know $\varx$ such that $\varh = \varg^\varx$ 17 | {{< /hint >}} 18 | 19 | * __Public input:__ cyclic group $\cgroup$ of prime order $\varq$, a $\cgroup$ generator $\varg$ and $\varh\in \cgroup$. 20 | * __Private input:__ $\varprover$ knows secret $\varx\in\zq$ such that $\varh = \varg^\varx$. 21 | 22 | We present all variants in their non-interactive version. 23 | 24 | ## Non-interactive protocols 25 | 26 | ### Original 27 | {{< rawhtml >}} 28 | $$ 29 | \begin{array}{c} 30 | \work{\varprover}{\varverifier} 31 | \alicework{\sampleNs{\varr}{\varq}} 32 | \alicework{\varu = \varg^\varr} 33 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 34 | \alicework{\varz = \varr + \varx\cdot \varc} 35 | \alicebob{}{\varu, \varc, \varz}{} 36 | \bobwork{\schnorrvalidate(\varu, \varh)} 37 | \bobwork{\varz \neq 0 \mod \varq} 38 | \bobseparator 39 | \bobwork{\varc \equalQ \hash{\varg, \varq, \varh, \varu}} 40 | \bobwork{\varg^\varz \equalQ \varu \cdot \varh ^\varc } 41 | \end{array} 42 | $$ 43 | {{< /rawhtml >}} 44 | 45 | ----- 46 | ### Slim Original 47 | In this variant, the prover does not send the value of $\varc$ which has to be computed by the verifier. 48 | {{< rawhtml >}} 49 | $$ 50 | \begin{array}{c} 51 | \work{\varprover}{\varverifier} 52 | \alicework{\sampleNs{\varr}{\varq}} 53 | \alicework{\varu = \varg^\varr} 54 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 55 | \alicework{\varz = \varr + \varx\cdot \varc} 56 | \alicebob{}{\varu, \varz}{} 57 | \bobwork{\schnorrvalidate(\varu, \varh)} 58 | \bobwork{\varz \neq 0 \mod \varq} 59 | \bobseparator 60 | \bobwork{\bar{\varc} = \hash{\varg, \varq, \varh, \varu}} 61 | \bobwork{\varg^\varz \equalQ \varu \cdot \varh ^\overline{\varc} } 62 | \end{array} 63 | $$ 64 | {{< /rawhtml >}} 65 | 66 | ----- 67 | 68 | ### Subtract 69 | In this variant, the prover uses a subtraction to compute the value of $\varz$. 70 | 71 | {{< rawhtml >}} 72 | $$ 73 | \begin{array}{c} 74 | \work{\varprover}{\varverifier} 75 | \alicework{\sampleNs{\varr}{\varq}} 76 | \alicework{\varu = \varg^\varr} 77 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 78 | \alicework{\varz = \varr - \varx\cdot \varc} 79 | \alicebob{}{\varu, \varc, \varz}{} 80 | \bobwork{\schnorrvalidate(\varu, \varh)} 81 | \bobwork{\varz \neq 0 \mod \varq} 82 | \bobseparator 83 | \bobwork{\varc \equalQ \hash{\varg, \varq, \varh, \varu}} 84 | \bobwork{\varg^\varz \cdot \varh ^\varc \equalQ \varu } 85 | \end{array} 86 | $$ 87 | {{< /rawhtml >}} 88 | 89 | ----- 90 | 91 | ### Subtract + Derive 92 | In this variant, the prover uses a subtraction to compute the value of $\varz$ and does not send $\varu$, which the verifier derives from the values they know. 93 | 94 | {{< rawhtml >}} 95 | $$ 96 | \begin{array}{c} 97 | \work{\varprover}{\varverifier} 98 | \alicework{\sampleNs{\varr}{\varq}} 99 | \alicework{\varu = \varg^\varr} 100 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 101 | \alicework{\varz = \varr - \varx\cdot \varc} 102 | \alicebob{}{\varc, \varz}{} 103 | \bobwork{\schnorrvalidate(\varh)} 104 | \bobwork{\varz \neq 0 \mod \varq} 105 | \bobseparator 106 | \bobwork{\bar{\varu} = \varg^\varz \cdot \varh^\varc} 107 | \bobwork{\bar{\varc} = \hash{\varg, \varq, \varh, \bar{\varu}}} 108 | \bobwork{\varc \equalQ \bar{\varc} } 109 | \end{array} 110 | $$ 111 | {{< /rawhtml >}} 112 | 113 | 114 | where $\schnorrvalidate(\varh)$ aborts if any of the following conditions are not met: 115 | * $\varh \neq 0 \text{ (point at infinity for EC groups)}$ and 116 | * $\varh \inQ \cgroup\text{ (on curve check for EC groups)}$. If called with two arguments, $\schnorrvalidate(\varu, \varh)$ will abort if any of the following conditions are not met by either argument. 117 | 118 | 119 | ## Security pitfalls 120 | These variants suffer from the same pitfalls as the original Schnorr scheme, with some adjustments when $\varz$ is computed with a subtraction: 121 | * **Verifier input validation:** Each of the items above the dotted line for the $\varverifier$ is essential to the security of the protocol. If any of these checks are missing or insufficient it is likely a severe security issue. 122 | * __Verifier trusts prover:__ 123 | * $\varverifier$ uses $g$ and $q$ provided in the proof instead of using publicly known values. 124 | * When the $\varprover$ sends $\varc$, if the $\varverifier$ assumes that the hash $\varc$ is correctly computed and does not compute it themself. Both are high severity issues since $\varprover$ can forge proofs. 125 | * __Weak Fiat-Shamir transformation:__ It is a common issue that some parameters are missing on the hash computation $\hash{\varg, \varq, \varh, \varu}$: 126 | * $\varh$ or $\varu$ missing: high severity issue. Read [Fiat-Shamir transformation]({{< ref "../protocol-primitives/fiat-shamir.md" >}}) for more details. 127 | * $\varg$ or $\varq$ missing: usually no issue, but it might be one if the Verifier uses these parameters directly from the proof structure. This way, the prover can provide bad generators or orders to forge the proof. 128 | * __Weak randomness:__ Bad randomness may cause the secret $\varx$ to leak. If $\varr$ is reused twice with two different non-interactive challenges then: 129 | $$ \frac{\varz - \varz'}{\varc-\varc'} = \frac{\varr -\varr + \varx\cdot(\varc - \varc')}{\varc-\varc'} = \varx \enspace,$$ 130 | or when $\varz$ is computed with a subtraction: 131 | $$ \frac{\varz - \varz'}{\varc'-\varc} = \frac{\varr -\varr + \varx\cdot(\varc' - \varc)}{\varc'-\varc} = \varx \enspace.$$ 132 | * __Replay attacks:__ After a non-interactive proof is public, it will always be valid and anyone could pretend to know the secret value. To prevent this, consider adding the ID of both the prover and the verifier inside of the Fiat-Shamir hash computation. 133 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/product-primes/square-freeness.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 2 3 | bookFlatSection: true 4 | title: "Number is square-free" 5 | summary: "Proves that a number is square-free." 6 | needsVariableResetButton: true 7 | references: ["GRSB19"] 8 | --- 9 | # Number is square-free 10 | 11 | To prove that a number is the product of two distinct primes, the first step is showing that the number is free of squares, i.e., that $\varN$ is 12 | not of the form $\varN = p^2 r$. 13 | 14 | This proof shows in zero-knowledge --without revealing the factors of the number-- that an element belongs to 15 | the set $$\sqfree = \\{\varN \in \naturals : \text{there is no prime }p \text{ such that }p^2\|N \\}.$$ 16 | 17 | The protocol uses the fact that an honest prover can calculate $\varN$-th roots of arbitrary numbers in $\z{\varN}$. 18 | 19 | {{< hint info >}} 20 | **Goal:** 21 | $\varprover$ convinces $\varverifier$ that $\varN$ is square-free without revealing its factorization. 22 | {{< /hint >}} 23 | 24 | * __Public input:__ $\varN\in\naturals$ 25 | * __Private input:__ $\varprover$ knows the factorization of $\varN = \varp\varq$ 26 | * __Security parameters:__ $\alpha, \kappa, m = \ceil{\kappa/ \log_2 \alpha}$ 27 | 28 | The protocol uses the constant $\displaystyle\Pi_\alpha = \prod_\underset{p\text{ prime}}{p<\alpha} p$, the product of the primes smaller than $\alpha$. 29 | 30 | We assume that both parties agree with the security parameters $\alpha, \kappa$ and $m$ prior to the execution of the protocol. 31 | 32 | ## Interactive protocol (HVZK) 33 | {{< hint danger >}} 34 | **Security note:** The protocol is zero-knowledge (does not reveal the factorization of $\varN$) only when the verifier is honest and generates each $\rhovar_i$ randomly. If the verifier chooses these values maliciously they can recover the factorization of $\varN$. If your attacker model takes this into consideration, use the non-interactive version. More details on [Using HVZKP in the wrong context](../../../security-of-zkps/when-to-use-hvzk). 35 | {{< /hint >}} 36 | 37 | {{< rawhtml >}} 38 | $$ 39 | \begin{array}{c} 40 | \work{\varprover}{\varverifier} 41 | \bobwork{\sampleN{\rhovar_i}{\varN}, \text{ for }i=1,\ldots,m} 42 | \bobalice{}{\{\rhovar_i\}_{i=1}^m}{} 43 | \alicework{\sigmavar_i = (\rhovar_i)^{\varN^{-1}\mod \varphi(\varN)} \mod \varN,} 44 | \alicework{\text{ for }i=1,\ldots,m} 45 | \alicebob{}{\{\sigmavar_i\}_{i=1}^m}{} 46 | \bobwork{\varN \gQ 1} 47 | \bobwork{\gcd(\varN, \Pi_\alpha) \equalQ 1} 48 | \bobwork{\sigmavar_i \mod \varN \gQ 0,} 49 | \bobseparator 50 | \bobwork{\rhovar_i \equalQ \sigmavar_i^\varN \mod \varN,} 51 | \bobwork{\text{ for }i=1,\ldots,m} 52 | \end{array} 53 | $$ 54 | {{< /rawhtml >}} 55 | 56 | 57 | ----- 58 | 59 | ## Non-interactive protocol 60 | The non-interactive version of the protocol replaces the verifier-side sampling of $\rhovar_i$ elements and generates them using the Fiat-Shamir transformation. 61 | The participants only exchange one message, and there is no risk of leaking the factorization of $\varN$ using maliciously chosen $\rhovar_i$ values. 62 | {{< rawhtml >}} 63 | $$ 64 | \begin{array}{c} 65 | \work{\varprover}{\varverifier} 66 | \alicework{\rhovar_i = \mathsf{gen}_\rhovar(\z{\varN}, \{\varN,i\})} 67 | \alicework{\sigmavar_i = (\rhovar_i)^{\varN^{-1}\mod \varphi(\varN)} \mod \varN,} 68 | \alicework{\text{ for }i=1,\ldots,m} 69 | \alicebob{}{\{\sigmavar_i\}_{i=1}^m}{} 70 | \bobwork{\varN \gQ 1} 71 | \bobwork{\gcd(\varN, \Pi_\alpha) \equalQ 1} 72 | \bobwork{\sigmavar_i \mod \varN \gQ 0 ,} 73 | \bobseparator 74 | \bobwork{\rhovar_i = \mathsf{gen}_\rhovar(\z{\varN}, \{\varN,i\})} 75 | \bobwork{\rhovar_i \equalQ \sigmavar_i^\varN \mod \varN,} 76 | \bobwork{\text{ for }i=1,\ldots,m} 77 | \end{array} 78 | $$ 79 | {{< /rawhtml >}} 80 | 81 | ## Security pitfalls 82 | * **Verifier input validation:** Each of the items above the dotted line for the $\varverifier$ is essential to the security of the protocol. If any of these checks are missing or insufficient it is likely a severe security issue. 83 | * __Using the interactive protocol in a malicious verifier context:__ high severity issue which allows factoring $\varN$; see [Using HVZKP in the wrong context]({{< relref "/docs/zkdocs/security-of-zkps/when-to-use-hvzk" >}}). 84 | * **Sampling $\rhovar_i$ values uniformly and not using honest generation:** high severity issue that allows $\varprover$ to forge proofs by sampling $\sampleSet{\sigmavar_i}{\z\varN}$ and setting $\rhovar_i = \sigmavar_i^\varN\mod \varN$. 85 | * __Verifier trusting prover on the non-interactive protocol:__ 86 | * $\varverifier$ uses $\rhovar_i$ values provided by $\varprover$ instead of generating them: this is a high severity issue since the prover can trivially forge proofs (e.g., by sending $\rhovar_i=1, \sigmavar_i=1$). 87 | * $\varverifier$ does not validate $\sigmavar_i$ as valid values modulo $\varN$ (between 0 and $\varN -1)$: this allows replaying the same proof with *different* values with $\sigmavar_i + k\varN$. 88 | * $\varverifier$ does not compare the number of received $\sigmavar_i$ with $m$: this can lead to the prover bypassing proof verification by sending an empty list, or fewer than $m$ elements. 89 | * __Replay attacks:__ After a non-interactive proof is public, it will always be valid and anyone could pretend to know how to prove the original statement. To prevent this, consider adding additional information to the generation of $\rhovar_i$ values such as an ID of both the prover and the verifier, and a timestamp. The verifier must check the validity of these values when they verify the proof. 90 | 91 | 92 | ## Auxiliary functions - $\mathsf{gen}_\rhovar$ 93 | - Generate the $\rhovar_i$ values with a standard [nothing-up-my-sleeve construction]({{< relref "/docs/zkdocs/protocol-primitives/nums.md" >}}) in $\z{\varN}$, use binding parameters $\\{\varN, i\\}$, bitsize of $|\varN|$, and salt $\mathsf{"squarefreeproof"}$. To prevent replay attacks consider including, in the binding parameters, ID's unique to the prover and verifier. 94 | 95 | 96 | 97 | ## Choice of security parameters $\alpha$, $\kappa$ 98 | 99 | The security of the protocol depends $\alpha$ and $\kappa$ which define the number of witnesses that $\varprover$ has to give $\varverifier$. The protocol achieves a statistical soundness error of $2^{-\kappa}$, which means $\varprover$ cannot cheat except with probability $2^{-\kappa}$. 100 | 101 | Parameter $\alpha$ is tunable and controls proving and verification time. Higher $\alpha$ values will generally decrease proving time and verification time, until some limit is reached and the verification time starts increasing. 102 | 103 | Recommended values for the security parameters are: 104 | - $\kappa = 128$ 105 | - $\alpha = 65537, 319567$ can be tried and the best performing one chosen. 106 | 107 | These values yield $m$ values of 108 | - $m(\kappa=128, \alpha=65537) = 8$ and 109 | - $m(\kappa=128, \alpha=319567) = 7$. 110 | 111 | 112 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/schnorr.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | bookFlatSection: true 4 | title: "Schnorr's identification protocol" 5 | summary: "The zero-knowledge proof for a discrete-logarithm in a prime modulo." 6 | needsVariableResetButton: true 7 | references: ["Sch91", "schnorr-lecture", "shake", "safe-primes"] 8 | --- 9 | # Schnorr's identification protocol 10 | Schnorr's identification protocol is the simplest example of a zero-knowledge protocol. With it, 11 | $\varprover$ can convince $\varverifier$ that they know the discrete logarithm $\varx$ of some value 12 | $\varh = \varg^\varx$, without revealing $\varx$. 13 | 14 | {{< hint info >}} 15 | **Goal:** 16 | $\varprover$ convinces $\varverifier$ that they know $\varx$ such that $\varh = \varg^\varx$. 17 | {{< /hint >}} 18 | 19 | * __Public input:__ cyclic group $\cgroup$ of prime order $\varq$, a $\cgroup$ generator $\varg$ and $\varh\in \cgroup$. 20 | * __Private input:__ $\varprover$ knows secret $\varx\in\zq$ such that $\varh = \varg^\varx$. 21 | 22 | 23 | {{< tabs "uniqueid" >}} 24 | {{< tab "Multiplicative notation" >}} 25 | ### Interactive protocol 26 | The Schnorr interactive identification protocol 27 | 28 | {{< rawhtml >}} 29 | $$ 30 | \begin{array}{c} 31 | \work{\varprover}{\varverifier} 32 | \alicework{\samplezqs{\varr}} 33 | \alicework{\varu = \varg^\varr} 34 | \alicebob{}{\varu}{} 35 | \bobwork{\schnorrvalidate(\varu, \varh)} 36 | \bobseparator 37 | \bobwork{\sample{\varc}} 38 | \bobalice{}{\varc}{} 39 | \alicework{\varz = \varr + \varx\cdot \varc} 40 | \alicebob{}{\varz}{} 41 | \bobwork{\varz \neq 0 \mod \varq} 42 | \bobseparator 43 | \bobwork{\varg^{\varz} \equalQ \varu \cdot \varh^\varc } 44 | \end{array} 45 | $$ 46 | 47 | {{< /rawhtml >}} 48 | ----- 49 | 50 | ### Non-interactive protocol 51 | We can transform this identification scheme into a non-interactive protocol using the Fiat-Shamir heuristic. Here, the prover creates the random challenge $c$ hashing *all* public values $\\{\varg, \varq, \varh, \varu\\}$. 52 | {{< rawhtml >}} 53 | $$ 54 | \begin{array}{c} 55 | \work{\varprover}{\varverifier} 56 | \alicework{\samplezqs{\varr}} 57 | \alicework{\varu = \varg^\varr} 58 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 59 | \alicework{\varz = \varr + \varx\cdot \varc} 60 | \alicebob{}{\varu, \varc, \varz}{} 61 | \bobwork{\schnorrvalidate(\varu, \varh)} 62 | \bobwork{\varz \neq 0 \mod \varq} 63 | \bobseparator 64 | \bobwork{\varc \equalQ \hash{\varg, \varq, \varh, \varu}} 65 | \bobwork{\varg^\varz \equalQ \varu \cdot \varh ^\varc } 66 | \end{array} 67 | $$ 68 | {{< /rawhtml >}} 69 | {{< /tab >}} 70 | 71 | 72 | {{< tab "Additive notation" >}} 73 | 74 | ### Interactive protocol 75 | The Schnorr interactive identification protocol 76 | 77 | 78 | {{< rawhtml >}} 79 | $$ 80 | \begin{array}{c} 81 | \work{\varprover}{\varverifier} 82 | \alicework{\samplezqs{\varr}} 83 | \alicework{\varu = \varr\cdot\varg} 84 | \alicebob{}{\varu}{} 85 | \bobwork{\schnorrvalidate(\varu, \varh)} 86 | \bobseparator 87 | \bobwork{\sample{\varc}} 88 | \bobalice{}{\varc}{} 89 | \alicework{\varz = \varr + \varx\cdot \varc} 90 | \alicebob{}{\varz}{} 91 | \bobwork{\varz \neq 0 \mod \varq} 92 | \bobseparator 93 | \bobwork{\varg^{\varz} \equalQ \varu \cdot \varh^\varc } 94 | \end{array} 95 | $$ 96 | 97 | 98 | 99 | {{< /rawhtml >}} 100 | 101 | ----- 102 | 103 | ### Non-interactive protocol 104 | We can transform this identification scheme into a non-interactive protocol using the Fiat-Shamir heuristic. Here, the prover creates the random challenge $c$ hashing *all* public values $\\{\varg, \varq, \varh, \varu\\}$. 105 | {{< rawhtml >}} 106 | $$ 107 | \begin{array}{c} 108 | \work{\varprover}{\varverifier} 109 | \alicework{\samplezqs{\varr}} 110 | \alicework{\varu = \varr\cdot \varg} 111 | \alicework{\varc = \hash{\varg, \varq, \varh, \varu}} 112 | \alicework{\varz = \varr + \varx\cdot \varc} 113 | \alicebob{}{\varu, \varc, \varz}{} 114 | \bobwork{\schnorrvalidate(\varu, \varh)} 115 | \bobwork{\varz \neq 0 \mod \varq} 116 | \bobseparator 117 | \bobwork{\varc \equalQ \hash{\varg, \varq, \varh, \varu}} 118 | \bobwork{\varz \cdot \varg \equalQ \varu + \varc\cdot\varh} 119 | \end{array} 120 | $$ 121 | {{< /rawhtml >}} 122 | {{< /tab >}} 123 | {{< /tabs >}} 124 | 125 | 126 | where $\schnorrvalidate(\varu, \varh)$ aborts if any of the following conditions are not met: 127 | * $\varu, \varh \neq 0 \text{ (point at infinity for EC groups)}$ and 128 | * $\varu, \varh \inQ \cgroup\text{ (on curve check for EC groups)}$. 129 | 130 | ## Security pitfalls 131 | * **Verifier input validation:** Each of the items above the dotted line for the $\varverifier$ is essential to the security of the protocol. If any of these checks are missing or insufficient it is likely a severe security issue. 132 | * __Verifier trusts prover:__ On the verification check, the verifier uses $g$ and $q$ provided with the proof instead of using publicly known values. On the NI version, the verifier assumes that the hash $\varc$ is correctly computed and does not compute it themself. Both are high severity issues since $\varprover$ can forge proofs. 133 | * __Weak Fiat-Shamir transformation:__ In the non-interactive protocol, it is a common occurrence that some parameters are missing on the hash computation $\hash{\varg, \varq, \varh, \varu}$: 134 | * $\varh$ or $\varu$ missing: high severity issue. Read [Fiat-Shamir transformation]({{< ref "../protocol-primitives/fiat-shamir.md" >}}) for more details. 135 | * $\varg$ or $\varq$ missing: usually no issue, but it might be one if the Verifier uses these parameters directly from the proof structure. This way, the prover can provide bad generators or orders to forge the proof. 136 | * __Weak randomness:__ Bad randomness may cause the secret $\varx$ to leak. If $\varr$ is reused twice with two different interactive challenges, or different data on the non-interactive version then 137 | $$ \frac{\varz - \varz'}{\varc-\varc'} = \frac{\varr -\varr + \varx\cdot(\varc - \varc')}{\varc-\varc'} = \varx $$ 138 | * __Replay attacks:__ After a non-interactive proof is public, it will always be valid and anyone could pretend to know the secret value. To prevent this, consider adding the ID of both the prover and the verifier inside of the Fiat-Shamir hash computation. 139 | 140 | 141 | ## Security assumptions 142 | * __Hash function:__ The hash function should be either [TupleHash](https://www.nist.gov/publications/sha-3-derived-functions-cshake-kmac-tuplehash-and-parallelhash) or SHA-256 where each input is domain separated with a unique string together with the length of each element. 143 | * __Hardness of the discrete logarithm:__ The order of the cyclic group $\cgroup$ should be at least $\varq>2^{K}$ where $K=256$, for a generic group $\cgroup$. If $\cgroup$ is a (prime-order) subgroup of $\zps$, then $p$ should be greater than $2^{\kappa}$ for $\kappa=3072$ to avoid [subexponential attacks](https://en.wikipedia.org/wiki/Index_calculus_algorithm) based on the extra structure of $\zps$. Note that this requires $p - 1 = q\cdot r$ with some potentially composite number $r$. Refer to table 2 (pp. 54-55) of [the NIST recommendations](https://doi.org/10.6028/NIST.SP.800-57pt1r5) for an overview of different bit security levels for finite field discrete logarithms. 144 | 145 | -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/fiat-shamir.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 2 3 | bookFlatSection: true 4 | title: "Fiat-Shamir transformation" 5 | references: ["FSWiki", "FS87", "ZKBlog", "BPW12", "RAWiki"] 6 | summary: "Here, we describe what the Fiat-Shamir transformation is, its goals, its pitfalls, and its different versions." 7 | --- 8 | # Fiat-Shamir transformation 9 | 10 | ## Overview 11 | 12 | It turns out that in practice, most zero-knowledge proofs tend to have the same three-step structure: 13 | 1. The prover first generates some random value, the commitment, and sends it to the verifier. 14 | 2. The verifier responds with a challenge value generated uniformly at random. 15 | 3. The prover computes the final proof based on both the commitment and challenge. 16 | 17 | As you can tell, this structure is interactive, meaning that the prover requires a response from the verifier before they can complete their proof, which is not ideal for most applications. Fortunately, provers can avoid this by using the [Fiat-Shamir heuristic](https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic) (sometimes referred to as the Fiat-Shamir transformation), [developed by Amos Fiat and Adi Shamir](https://link.springer.com/content/pdf/10.1007%2F3-540-47721-7_12.pdf). 18 | 19 | The idea behind the Fiat-Shamir transformation is that instead of having the verifier send a random challenge value to the prover, the prover can compute this value themselves by using a random function, such as a cryptographic hash function. 20 | 21 | {{< hint info >}} 22 | **Example:** In the [Schnorr protocol]({{< ref "../zero-knowledge-protocols/schnorr.md" >}}), we have an interactive and non-interactive version. In the interactive version, the prover sends their random commitment, $u = g^r$, and the verifier responds with a challenge value, $c$, that they generate uniformly at random. In the non-interactive version, the prover generates $c$ themselves by computing a hash over all of the public values, $c = \hash{g,q,h,u}$. As we will discuss, the hash must include all of these values. 23 | {{< /hint >}} 24 | 25 | If you'd like to read more about this, we've written a [blog post describing how they work in more detail](https://blog.trailofbits.com/2021/02/19/serving-up-zero-knowledge-proofs/). 26 | 27 | ## What can go wrong? 28 | 29 | This transformation may seem straightforward, but unfortunately, it tends to be very tricky in practice. In particular, the prover generates the random challenge value using a cryptographic hash function- but what are the inputs? It turns out that if you choose the wrong inputs, it usually means your proof system is broken. To see this, let's look at [Schnorr's protocol]({{< ref "../zero-knowledge-protocols/schnorr.md" >}}) as an example. 30 | 31 | {{< hint danger >}} 32 | **Bad example, NEVER DO THIS:** Recall that in the [Schnorr protocol]({{< ref "../zero-knowledge-protocols/schnorr.md" >}}), the prover generates their random commitment, $u = g^r$, computes the challenge value, $c$, and then computes the final proof $z = r + x\cdot c$, where $x$ is the secret value corresponding to their public key, $h = g^x$. Let's say the implementation is incorrect, and the challenge value, $c$, is not computed using the public key, $h$, and instead it's computed as $c = \hash{g,q,u}$. It turns out that malicious provers can now forge proofs by doing the following attack: 33 | 34 | - Set the commitment value, $u$, to be some public key that you do not know the secret key for. 35 | - Compute the challenge value $c = \hash{g,q,u}$. 36 | - Set the proof $z$ to be a random value, and then compute your public key to be $h = (\frac{g^z}{u})^{\frac{1}{c}}$ 37 | - Send $u,c,z$ to the verifier. 38 | 39 | The verifier then performs their two checks: $c \equalQ \hash{g,q,u}$ and $g^z \equalQ u\cdot h^c$. The first check will pass as they are both the same, and the second check will pass because of how we constructed $z$, $u$, and $h$. 40 | 41 | Since we set $u$ to be some value we do not know the secret key for, we also will not know the secret key for $h$, which means we have forged our proof of knowledge. 42 | 43 | **Note:** This attack does not allow you to forge proofs for any public key, this only works for random public keys. This tends not to be problematic when Schnorr proofs as a proof of knowledge in the typical public-key model. However, this can be very problematic when these proofs are used in other scenarios, such as a [cryptographic voting system](https://eprint.iacr.org/2016/771.pdf). 44 | {{< /hint >}} 45 | 46 | ## Recommendations 47 | 48 | ### Rule of thumb 49 | 50 | The exact inputs required for the hash function will be different for every zero-knowledge proof system. The general rule of thumb to follow is to include all of the public information and all elements in the proof transcript up until that point inside the hash function. 51 | 52 | {{< hint info >}} 53 | In the [Schnorr protocol]({{< ref "../zero-knowledge-protocols/schnorr.md" >}}), the public information is the public key, $h$, and the parameters related to the group being used, $g$ and $q$, and the proof transcript also includes the commitment value, $u$, and so we include all of those values in our hash computation. 54 | {{< /hint >}} 55 | 56 | {{< hint info >}} 57 | For [short factoring proof protocol]({{< ref "../zero-knowledge-protocols/short-factoring-proofs.md" >}}), it's a bit more complicated. The public information is the number the prover can factor, $N$, so this must be included. What about transcript values? In this scheme, the prover does a bit more work before computing the challenge compared to the [Schnorr protocol]({{< ref "../zero-knowledge-protocols/schnorr.md" >}}). Specifically, they generate a random value ($r$), a series of values ($z_i$) using the [nothing-up-my-sleeve construction]({{< ref "nums.md" >}}), and then they compute $X = \hash{\bunchi{z_i^r \mod N}}$ (this is not the Fiat-Shamir challenge). Since both the $X$ value and the set of $z_i$ values will be known to the verifier (i.e., they are part of the transcript), these must also be included in the hash computation. So, the correct challenge computation is $e = \hash{N, \bunchi{z_i}, X}$. 58 | 59 | **Note:** In the short factoring proof and in [Girault's scheme]({{< ref "../zero-knowledge-protocols/girault-identification" >}}), the Fiat-Shamir challenge needs to additionally be of a specific bit-size. So, the correct computation is actually $e = \hashbit{N, \bunchi{z_i}, X}{k}$. 60 | {{< /hint >}} 61 | 62 | **Remember:** Always include all public information and all transcript values. When in doubt, consult ZKDocs! 63 | 64 | ### Preventing replay attacks 65 | 66 | Just like digital signatures, zero-knowledge proofs can also be susceptible to [replay attacks](https://en.wikipedia.org/wiki/Replay_attack). As is the case for other replay attacks, the severity of these replay attacks will be highly application and context-specific. 67 | 68 | If you believe replay attacks could be severe for your application, you might be able to use the Fiat-Shamir transformation to protect yourself. Specifically, suppose your application has some notion of identity tied to each party (a unique party ID, for example). In that case, you should include the ID of the prover and the verifier inside the Fiat-Shamir hash computation. Then, when the verifier verifies the proof, they should also check that the IDs used in the hash function match the ID of themself and the prover. This will prevent other malicious parties from replaying any proof that they did not produce themselves. 69 | -------------------------------------------------------------------------------- /content/docs/zkdocs/zero-knowledge-protocols/product-primes/product-of-two-primes.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 5 3 | title: "Product of two primes" 4 | needsVariableResetButton: true 5 | summary: "Proves that a number is the product of two distinct primes: in parallel, run the square-freeness proof together with the two-prime-divisors proof." 6 | references: ["GRSB19", "jacobi", "AP18", "hoc"] 7 | --- 8 | ## Number is the product of two primes 9 | 10 | To show that a number is the product of two distinct primes, we make use of the previous protocols to show that: 11 | - $\varN$ is [square-free](../square-freeness) 12 | - $\varN$ [only has two divisors](../two-prime-divisors) 13 | 14 | Formally, we show that $\varN$ is in the set $$L_{pp} = \\{N \in \naturals | N \text{ is odd and is the product of two distinct primes}\\} = L_{ppp} \cap \sqfree.$$ 15 | For this, we run the protocols from [Square-free](../square-freeness) and [Two prime divisors](../two-prime-divisors) in parallel for the same $N$. 16 | 17 | {{< hint info >}} 18 | **Goal:** 19 | $\varprover$ convinces $\varverifier$ that $\varN$ is the product of two distinct primes without revealing its factorization. 20 | {{< /hint >}} 21 | 22 | * __Public input:__ $\varN\in\naturals$ 23 | * __Private input:__ $\varprover$ knows the factorization of $\varN = \varp\varq$ 24 | * __Security parameters:__ $\alpha, \kappa, m_1 = \ceil{\kappa/ \log_2 \alpha}$, $m_2 = \ceil{\kappa \cdot 32 \cdot \ln(2)}$ 25 | 26 | We only present the non-interactive version of this protocol, suitable to use in the context of malicious verifiers. 27 | 28 | ## Non-interactive protocol 29 | 30 | {{< rawhtml >}} 31 | $$ 32 | \begin{array}{c} 33 | \work{\varprover}{\varverifier} 34 | \alicework{\rhovar_i = \mathsf{gen}_\rhovar(\z{\varN}, \{\varN,i\})} 35 | \alicework{\sigmavar_i = (\rhovar_i)^{\varN^{-1}\mod \varphi(\varN)} \mod \varN,} 36 | \alicework{\text{ for }i=1,\ldots,m_1} 37 | \aliceseparator 38 | \alicework{\thetavar_i = \mathsf{gen}_\rhovar(J_\varN, \{\varN, m_1 + i, F\})} 39 | \alicework{\muvar_i = \begin{cases} 40 | \sqrt{\thetavar_i} \mod \varN &\text{ if }\thetavar_i \in QR_\varN \\ 41 | 0 &\text{ otherwise} 42 | \end{cases} 43 | } 44 | \alicework{\text{ for }i=1,\ldots,m_2} 45 | \alicebob{}{\{\sigmavar_i\}_{i=1}^{m_1}, \{\muvar_i\}_{i=1}^{m_2}, F}{} 46 | \bobwork{\varN \gQ 1} 47 | \bobwork{\varN \mod 2 \equalQ 1} 48 | \bobwork{\mathsf{isPrime}(\varN) \equalQ false} 49 | \bobwork{\mathsf{isPrimePower}(\varN) \equalQ false} 50 | \bobwork{\gcd(\varN, \Pi_\alpha) \equalQ 1} 51 | \bobwork{\sigmavar_i \mod \varN \gQ 0,} 52 | \bobseparator 53 | \bobwork{\rhovar_i = \mathsf{gen}_\rhovar(\z{\varN}, \{\varN,i\})} 54 | \bobwork{\rhovar_i \equalQ \sigmavar_i^\varN \mod \varN,} 55 | \bobwork{\text{ for }i=1,\ldots,m_1} 56 | \bobwork{\thetavar_i = \mathsf{gen}_\rhovar(J_\varN, \{\varN, m_1 + i, F\})} 57 | \bobwork{|\{\muvar_i \text{ for }i=1,\ldots,m| \muvar_i \neq 0 \mod \varN\}| \gQ 3m_2/8} 58 | \bobwork{\text{if } \muvar_i \neq 0 \mod \varN \text{ then }\thetavar_i \equalQ \muvar_i^2 \mod \varN} 59 | \bobwork{\text{ for }i=1,\ldots,m_2} 60 | \end{array} 61 | $$ 62 | {{< /rawhtml >}} 63 | 64 | ## Security parameters 65 | - $\kappa = 128$ 66 | - $m_1(\kappa=128, \alpha=65537) = 8$ 67 | - $m_2(\kappa=128) = 2840$ 68 | 69 | ## Security pitfalls 70 | This protocol suffers from the same pitfalls as the [Square-free](../square-freeness#security-pitfalls) and [Two prime divisors](../two-prime-divisors#security-pitfalls) protocols. We include them here for clarity: 71 | * **Verifier input validation:** Each of the items above the dotted line for the $\varverifier$ is essential to the security of the protocol. If any of these checks are missing or insufficient it is likely a severe security issue. 72 | * **Sampling the $\rhovar_i$ or $\thetavar_i$ values uniformly and not using honest generation:** high severity issue that allows $\varprover$ to forge proofs by sampling $\sampleSet{\sigmavar_i,\muvar_i}{\z\varN}$, and setting $\rhovar_i = \sigmavar_i^\varN\mod \varN$ and $\thetavar_i = \muvar_i^2\mod \varN$ . 73 | * **Failing to include a fresh value in $\mathsf{gen}_\rhovar$ to generate $\thetavar_i$:** potential high severity issue since this means that all proofs for the same $\varN$ will have the same $\thetavar_i$ values; if the prover uses a probabilistic algorithm to compute square-roots, he can leak two different square-roots of the same value, allowing an attacker to factor $\varN$ using the same attack as [Using HVZKP in the wrong context]({{< relref "/docs/zkdocs/security-of-zkps/when-to-use-hvzk#the-case-of-the-two-prime-divisor-proof" >}}). If the square-root algorithm always returns the same square-root for a given $\rhovar_i$ this is not an issue. 74 | * __Verifier trusting prover on the non-interactive protocol:__ 75 | * $\varverifier$ uses $\rhovar_i$ or $\thetavar_i$ values provided by $\varprover$ instead of generating them: this is a high severity issue since the prover can trivially forge proofs (e.g., by sending $\rhovar_i=1, \sigmavar_i=1$ and $\thetavar_i = 1, \muvar_i=1$). 76 | * $\varverifier$ does not validate $\sigmavar_i$, $\muvar_i$ as valid values modulo $\varN$ (between 0 and $\varN -1)$: this allows replaying the same proof with *different* values with $\sigmavar_i + k\varN$, $\muvar_i + k'\varN$. 77 | * $\varverifier$ does not compare the number of received $\sigmavar_i$ with $m_1$ and $\muvar_i$ with $m_2$: this can lead to the prover bypassing proof verification by sending an empty list, or fewer than $m_1$ or $m_2$ elements. 78 | * __Replay attacks:__ After a non-interactive proof is public, it will always be valid and anyone could pretend to know how to prove the original statement. To prevent this, consider adding additional information to the generation of $\rhovar_i$ and $\thetavar_i$ values such as an ID of both the prover and the verifier, and a timestamp. The verifier must check the validity of these values when they verify the proof. 79 | 80 | 81 | ## Performance considerations 82 | For the desired security level of $\kappa=128$, we need to generate 2840 $\muvar_i$ elements. Because of this, this proof system can be very computationally expensive. If this dramatically affects the performance of your protocol, and your $\varN$ is the product of two primes congruent with $3\mod 4$, we recommend using an alternative proof system, the [Paillier-Blum modulus](../paillier_blum_modulus) proof. 83 | 84 | ## Honest parameter generation $\mathsf{gen}_\rhovar$ 85 | - Generate the $\rhovar_i$ and $\thetavar_i$ values with a standard [nothing-up-my-sleeve construction]({{< relref "/docs/zkdocs/protocol-primitives/nums.md" >}}): 86 | - $\rhovar_i$ in $\z{\varN}$, use binding parameters $\\{\varN, i\\}$, bitsize of $|\varN|$, and salt $\mathsf{"productoftwoprimesproof"}$. 87 | - $\thetavar_i$ in $J_{\varN}$, use binding parameters $\\{\varN, i, F\\}$, bitsize of $|\varN|$, and salt $\mathsf{"productoftwoprimesproof"}$. $F$ should be a fresh value unique to the current proof. 88 | - To prevent replay attacks consider including, in the binding parameters, ID's unique to the prover and verifier. 89 | 90 | ## Auxiliary algorithms 91 | - To calculate the [Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol) use Algorithm 2.149 of the [Handbook of Applied Cryptography](https://cacr.uwaterloo.ca/hac/). 92 | 93 | - To calculate square-roots modulo $\varN$ use Algorithm 3.44 of the [Handbook of Applied Cryptography](https://cacr.uwaterloo.ca/hac/). 94 | 95 | - To implement $\mathsf{isPrimePower}$, a simple algorithm is [here](https://cstheory.stackexchange.com/questions/2077/how-to-check-if-a-number-is-a-perfect-power-in-polynomial-time) and also explained on page 3 of the [AKS paper](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.532.7639&rep=rep1&type=pdf). Note 3.6 of the [Handbook of Applied Cryptography](https://cacr.uwaterloo.ca/hac/about/chap3.pdf) also has a description. 96 | 97 | - Most libraries will have a primality testing routine for the $\mathsf{isPrime}$ function. -------------------------------------------------------------------------------- /themes/book/assets/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; /* 1 */ 13 | -webkit-text-size-adjust: 100%; /* 2 */ 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; /* 1 */ 55 | height: 0; /* 1 */ 56 | overflow: visible; /* 2 */ 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; /* 1 */ 66 | font-size: 1em; /* 2 */ 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; /* 1 */ 87 | text-decoration: underline; /* 2 */ 88 | text-decoration: underline dotted; /* 2 */ 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; /* 1 */ 109 | font-size: 1em; /* 2 */ 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: 1.15; /* 1 */ 168 | margin: 0; /* 2 */ 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { /* 1 */ 178 | overflow: visible; 179 | } 180 | 181 | /** 182 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 183 | * 1. Remove the inheritance of text transform in Firefox. 184 | */ 185 | 186 | button, 187 | select { /* 1 */ 188 | text-transform: none; 189 | } 190 | 191 | /** 192 | * Correct the inability to style clickable types in iOS and Safari. 193 | */ 194 | 195 | /* button, 196 | [type="button"], 197 | [type="reset"], 198 | [type="submit"] { 199 | -webkit-appearance: button; 200 | } */ 201 | 202 | /** 203 | * Remove the inner border and padding in Firefox. 204 | */ 205 | 206 | /* button::-moz-focus-inner, 207 | [type="button"]::-moz-focus-inner, 208 | [type="reset"]::-moz-focus-inner, 209 | [type="submit"]::-moz-focus-inner { 210 | border-style: none; 211 | padding: 0; 212 | } */ 213 | 214 | /** 215 | * Restore the focus styles unset by the previous rule. 216 | */ 217 | 218 | /* button:-moz-focusring, 219 | [type="button"]:-moz-focusring, 220 | [type="reset"]:-moz-focusring, 221 | [type="submit"]:-moz-focusring { 222 | outline: 1px dotted ButtonText; 223 | } */ 224 | 225 | /** 226 | * Correct the padding in Firefox. 227 | */ 228 | 229 | fieldset { 230 | padding: 0.35em 0.75em 0.625em; 231 | } 232 | 233 | /** 234 | * 1. Correct the text wrapping in Edge and IE. 235 | * 2. Correct the color inheritance from `fieldset` elements in IE. 236 | * 3. Remove the padding so developers are not caught out when they zero out 237 | * `fieldset` elements in all browsers. 238 | */ 239 | 240 | legend { 241 | box-sizing: border-box; /* 1 */ 242 | color: inherit; /* 2 */ 243 | display: table; /* 1 */ 244 | max-width: 100%; /* 1 */ 245 | padding: 0; /* 3 */ 246 | white-space: normal; /* 1 */ 247 | } 248 | 249 | /** 250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 251 | */ 252 | 253 | progress { 254 | vertical-align: baseline; 255 | } 256 | 257 | /** 258 | * Remove the default vertical scrollbar in IE 10+. 259 | */ 260 | 261 | textarea { 262 | overflow: auto; 263 | } 264 | 265 | /** 266 | * 1. Add the correct box sizing in IE 10. 267 | * 2. Remove the padding in IE 10. 268 | */ 269 | 270 | [type="checkbox"], 271 | [type="radio"] { 272 | box-sizing: border-box; /* 1 */ 273 | padding: 0; /* 2 */ 274 | } 275 | 276 | /** 277 | * Correct the cursor style of increment and decrement buttons in Chrome. 278 | */ 279 | 280 | [type="number"]::-webkit-inner-spin-button, 281 | [type="number"]::-webkit-outer-spin-button { 282 | height: auto; 283 | } 284 | 285 | /** 286 | * 1. Correct the odd appearance in Chrome and Safari. 287 | * 2. Correct the outline style in Safari. 288 | */ 289 | 290 | [type="search"] { 291 | -webkit-appearance: textfield; /* 1 */ 292 | outline-offset: -2px; /* 2 */ 293 | } 294 | 295 | /** 296 | * Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | [type="search"]::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /** 304 | * 1. Correct the inability to style clickable types in iOS and Safari. 305 | * 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; /* 1 */ 310 | font: inherit; /* 2 */ 311 | } 312 | 313 | /* Interactive 314 | ========================================================================== */ 315 | 316 | /* 317 | * Add the correct display in Edge, IE 10+, and Firefox. 318 | */ 319 | 320 | details { 321 | display: block; 322 | } 323 | 324 | /* 325 | * Add the correct display in all browsers. 326 | */ 327 | 328 | summary { 329 | display: list-item; 330 | } 331 | 332 | /* Misc 333 | ========================================================================== */ 334 | 335 | /** 336 | * Add the correct display in IE 10+. 337 | */ 338 | 339 | template { 340 | display: none; 341 | } 342 | 343 | /** 344 | * Add the correct display in IE 10. 345 | */ 346 | 347 | [hidden] { 348 | display: none; 349 | } 350 | -------------------------------------------------------------------------------- /themes/book/layouts/partials/docs/header.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | $\newcommand{\coinheads}{\mathsf{HEADS}}$ 23 | $\newcommand{\cointails}{\mathsf{TAILS}}$ 24 | $\newcommand{\varalice}{\class{var var_Alice}{\text{Alice}}}$ 25 | $\newcommand{\varbob}{\class{var var_Bob}{\text{Bob}}}$ 26 | $\newcommand{\alicebob}[3]{#1 & \ra{#2} & #3\\[-5pt]}$ 27 | $\newcommand{\bobalice}[3]{#1 & \la{#2} & #3\\[-5pt]}$ 28 | $\newcommand{\alicework}[1]{#1 & &\\[-5pt]}$ 29 | $\newcommand{\bobwork}[1]{ & & #1\\[-5pt]}$ 30 | $\newcommand{\work}[2]{#1 & & #2\\}$ 31 | $\newcommand{\allwork}[1]{ & #1 & \\}$ 32 | $\newcommand{\dupwork}[1]{#1 & & #1\\}$ 33 | $\newcommand{\aliceseparator}{-------&&\\}$ 34 | $\newcommand{\bobseparator}{&&-------\\}$ 35 | $\newcommand{\foo}{\phantom{\text{bigarrowfitsallthis}}}$ 36 | $\newcommand{\ra}[1]{% 37 | \vphantom{\xrightarrow{asd}}% 38 | \smash{\xrightarrow[\foo]{#1}}% 39 | }$ 40 | $\newcommand{\la}[1]{% 41 | \vphantom{\xleftarrow{asd}}% 42 | \smash{\xleftarrow[\foo]{#1}}% 43 | }$ 44 | $\newcommand{\z}[1]{\mathbb{Z}_{#1}}$ 45 | $\newcommand{\zq}{\mathbb{Z}_\varq}$ 46 | $\newcommand{\zqs}{\mathbb{Z}_q^\ast}$ 47 | $\newcommand{\zps}{\mathbb{Z}_p^\ast}$ 48 | $\newcommand{\zns}[1]{\mathbb{Z}_{#1}^\ast}$ 49 | $\require{action} 50 | \newcommand{\sampleSymb}{ 51 | {\overset{\$}{\leftarrow}} 52 | }$ 53 | $\newcommand{\field}[1]{\mathbb{F}_{#1}}$ 54 | $\newcommand{\sample}[1]{#1\sampleSymb\zq}$ 55 | $\newcommand{\sampleGeneric}[2]{#1\sampleSymb#2}$ 56 | $\newcommand{\sampleInterval}[2]{#1\sampleSymb\interval{#2}}$ 57 | $\newcommand{\sampleRange}[2]{#1\sampleSymb\range{#2}}$ 58 | $\newcommand{\sampleCgroup}[1]{#1\sampleSymb\cgroup}$ 59 | $\newcommand{\samplezqs}[1]{\class{hover}{#1\sampleSymb\zqs}}$ 60 | $\newcommand{\sampleN}[2]{\class{hover}{#1\sampleSymb\z{#2}}}$ 61 | $\newcommand{\sampleNs}[2]{\class{hover}{#1\sampleSymb\z{#2}^\ast}}$ 62 | $\newcommand{\equalQ}{\overset{?}{=}}$ 63 | $\newcommand{\gQ}{\overset{?}{>}}$ 64 | $\newcommand{\inQ}{\overset{?}{\in}}$ 65 | $\newcommand{\cgroup}{\mathbb{G}}$ 66 | $\newcommand{\Hash}{\mathsf{Hash}}$ 67 | $\newcommand{\hash}[1]{\Hash({#1})}$ 68 | $\newcommand{\HashToField}{\mathsf{HashToField}}$ 69 | $\newcommand{\hashtofield}[1]{\HashToField({#1})}$ 70 | $\newcommand{\HashToGroup}{\mathsf{HashToGroup}}$ 71 | $\newcommand{\hashtogroup}[1]{\HashToGroup({#1})}$ 72 | $\newcommand{\hashbit}[2]{\mathsf{Hash}({#1})\verb+[0:#2]+}$ 73 | $\newcommand{\hmac}[2]{\mathsf{HMAC}_{#1}\left(#2\right)}$ 74 | $\newcommand{\naturals}{\mathbb{N}}$ 75 | $\newcommand{\sqfree}{L_\mathsf{square-free}}$ 76 | $\newcommand{\ceil}[1]{\lceil #1 \rceil}$ 77 | $\newcommand{\sampleSet}[2]{\class{hover}{#1\sampleSymb#2}}$ 78 | $\newcommand{\bunch}[1]{\{ #1_i\}_{i=1}^m}$ 79 | $\newcommand{\bunchi}[1]{\{ #1\}_{i=1}^m}$ 80 | $\newcommand{\forb}{\text{ for }i=1,\ldots,m}$ 81 | $\newcommand{\interval}[1]{[0, #1[}$ 82 | 83 | $\newcommand{\range}[1]{[#1]}$ 84 | $\newcommand{\rangeone}[1]{\{1, \dots,#1 -1 \}}$ 85 | 86 | 87 | 88 | $\newcommand{\vara}{\class{var var_a}{a}}$ 89 | $\newcommand{\varb}{\class{var var_b}{b}}$ 90 | $\newcommand{\varc}{\class{var var_c}{c}}$ 91 | $\newcommand{\vard}{\class{var var_d}{d}}$ 92 | $\newcommand{\varh}{\class{var var_h}{h}}$ 93 | $\newcommand{\varH}{\class{var var_H}{H}}$ 94 | $\newcommand{\varg}{\class{var var_g}{g}}$ 95 | $\newcommand{\varG}{\class{var var_G}{G}}$ 96 | $\newcommand{\vari}{\class{var var_i}{i}}$ 97 | $\newcommand{\varj}{\class{var var_j}{j}}$ 98 | $\newcommand{\vars}{\class{var var_s}{s}}$ 99 | $\newcommand{\vart}{\class{var var_t}{t}}$ 100 | $\newcommand{\varu}{\class{var var_u}{u}}$ 101 | $\newcommand{\varU}{\class{var var_U}{U}}$ 102 | $\newcommand{\varl}{\class{var var_l}{l}}$ 103 | $\newcommand{\varm}{\class{var var_m}{m}}$ 104 | $\newcommand{\varn}{\class{var var_n}{n}}$ 105 | $\newcommand{\varx}{\class{var var_x}{x}}$ 106 | $\newcommand{\varX}{\class{var var_X}{X}}$ 107 | $\newcommand{\varz}{\class{var var_z}{z}}$ 108 | $\newcommand{\varr}{\class{var var_r}{r}}$ 109 | $\newcommand{\varq}{\class{var var_q}{q}}$ 110 | $\newcommand{\varp}{\class{var var_p}{p}}$ 111 | $\newcommand{\vare}{\class{var var_e}{e}}$ 112 | $\newcommand{\vary}{\class{var var_y}{y}}$ 113 | $\newcommand{\varv}{\class{var var_v}{v}}$ 114 | $\newcommand{\varw}{\class{var var_w}{w}}$ 115 | $\newcommand{\varC}{\class{var var_C}{C}}$ 116 | $\newcommand{\varf}{\class{var var_f}{f}}$ 117 | $\newcommand{\varA}{\class{var var_A}{A}}$ 118 | $\newcommand{\varB}{\class{var var_B}{B}}$ 119 | $\newcommand{\varC}{\class{var var_C}{C}}$ 120 | $\newcommand{\varL}{\class{var var_L}{L}}$ 121 | $\newcommand{\varP}{\class{var var_P}{P}}$ 122 | $\newcommand{\varR}{\class{var var_R}{R}}$ 123 | $\newcommand{\varT}{\class{var var_T}{T}}$ 124 | $\newcommand{\varX}{\class{var var_X}{X}}$ 125 | $\newcommand{\varalpha}{\class{var var_alpha}{\alpha}}$ 126 | 127 | $\newcommand{\varprover}{\class{var var_Prover}{\text{Prover}}}$ 128 | $\newcommand{\varprover}{\class{var var_Prover}{\text{Prover}}}$ 129 | $\newcommand{\varverifier}{\class{var var_Verifier}{\text{Verifier}}}$ 130 | $\newcommand{\varN}{\class{var var_N}{N}}$ 131 | $\newcommand{\rhovar}{\class{var var_ρ}{\rho}}$ 132 | $\newcommand{\sigmavar}{\class{var var_σ}{\sigma}}$ 133 | $\newcommand{\thetavar}{\class{var var_θ}{\theta}}$ 134 | $\newcommand{\muvar}{\class{var var_μ}{\mu}}$ 135 | 136 | 137 | $\renewcommand{\vec}[1]{\mathbf{#1}}$ 138 | 139 | $\newcommand{\veca}{\vec{\class{var var_vec_a}{a}}}$ 140 | $\newcommand{\vecb}{\vec{\class{var var_vec_b}{b}}}$ 141 | $\newcommand{\vecc}{\vec{\class{var var_vec_c}{c}}}$ 142 | $\newcommand{\vecs}{\vec{\class{var var_vec_s}{s}}}$ 143 | $\newcommand{\vecG}{\vec{\class{var var_vec_G}{G}}}$ 144 | $\newcommand{\vecH}{\vec{\class{var var_vec_H}{H}}}$ 145 | $\newcommand{\vecg}{\vec{\class{var var_vec_g}{g}}}$ 146 | $\newcommand{\vech}{\vec{\class{var var_vec_h}{h}}}$ 147 | 148 | $\newcommand{\true}{\mathsf{true}}$ 149 | $\newcommand{\false}{\mathsf{false}}$ 150 | $\newcommand{\ctx}{\mathsf{ctx}}$ 151 | 152 | $\newcommand{\coloneqq}{≔}$ 153 | $\newcommand{\ip}[2]{\left\langle #1, #2 \right\rangle}$ 154 | 155 | $\newcommand{\uwork}[2]{\underline{#1} & & \underline{#2}\\}$ 156 | 157 | $\newcommand{\aliceworks}[1]{#1 & &\\[-2pt]}$ 158 | $\newcommand{\bobworks}[1]{ & & #1\\[-2pt]}$ 159 | 160 | $\newcommand{\Halving}{\text{Halving}}$ 161 | $\newcommand{\HalveProof}{\text{HalveProof}}$ 162 | $\newcommand{\HalveVerify}{\text{HalveVerify}}$ 163 | 164 | $\newcommand{\indent}{\qquad}$ 165 | $\newcommand{\append}{\mathrm{append}}$ 166 | 167 | 168 | $\newcommand{\schnorrvalidate}{\mathsf{schnorr}\_\mathsf{validate}}$ 169 | 170 |
    171 | 174 | 175 | {{ partial "docs/title" . }} 176 | 177 | 182 |
    183 | 184 | -------------------------------------------------------------------------------- /themes/book/assets/_main.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: $font-size-base; 3 | scroll-behavior: smooth; 4 | touch-action: manipulation; 5 | } 6 | 7 | body { 8 | min-width: $body-min-width; 9 | color: var(--body-font-color); 10 | background: var(--body-background); 11 | 12 | letter-spacing: 0.33px; 13 | font-weight: $body-font-weight; 14 | text-rendering: optimizeLegibility; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | 18 | box-sizing: border-box; 19 | 20 | * { 21 | box-sizing: inherit; 22 | } 23 | } 24 | 25 | h1, 26 | h2, 27 | h3, 28 | h4, 29 | h5 { 30 | font-weight: $body-font-weight; 31 | } 32 | 33 | a { 34 | text-decoration: none; 35 | color: var(--color-link); 36 | } 37 | 38 | button { 39 | color: black; 40 | background-color: gray; 41 | } 42 | 43 | .button:hover { 44 | background-color: white; 45 | cursor: pointer 46 | } 47 | 48 | 49 | img { 50 | vertical-align: baseline; 51 | } 52 | 53 | :focus { 54 | @include outline; 55 | } 56 | 57 | aside nav ul { 58 | padding: 0; 59 | margin: 0; 60 | list-style: none; 61 | 62 | li { 63 | margin: 1em 0; 64 | position: relative; 65 | } 66 | 67 | a { 68 | display: block; 69 | } 70 | 71 | a:hover { 72 | opacity: 0.5; 73 | } 74 | 75 | ul { 76 | padding-inline-start: $padding-16; 77 | } 78 | } 79 | 80 | ul.pagination { 81 | display: flex; 82 | justify-content: center; 83 | list-style-type: none; 84 | 85 | .page-item a { 86 | padding: $padding-16; 87 | } 88 | } 89 | 90 | .container { 91 | max-width: $container-max-width; 92 | margin: 0 auto; 93 | } 94 | 95 | .book-icon { 96 | filter: var(--icon-filter); 97 | } 98 | 99 | .book-brand { 100 | margin-top: 0; 101 | margin-bottom: $padding-16; 102 | 103 | #icon { 104 | height: 4.5em; 105 | width: 4.5em; 106 | margin-left: auto; 107 | display: block; 108 | margin-right: auto; 109 | // margin-bottom: -0.5em; 110 | margin-top: -0.7em; 111 | } 112 | 113 | #logo { 114 | height: 1.5em; 115 | width: 1.5em; 116 | margin-inline-end: $padding-8; 117 | } 118 | 119 | } 120 | 121 | .book-menu { 122 | flex: 0 0 $menu-width; 123 | font-size: $font-size-14; 124 | 125 | .book-menu-content { 126 | width: $menu-width; 127 | padding: $padding-16; 128 | background: var(--body-background); 129 | 130 | @include fixed; 131 | } 132 | 133 | a, 134 | label { 135 | color: inherit; 136 | cursor: pointer; 137 | word-wrap: break-word; 138 | } 139 | 140 | a.active { 141 | color: var(--color-link); 142 | } 143 | 144 | input.toggle+label+ul { 145 | display: none; 146 | } 147 | 148 | input.toggle:checked+label+ul { 149 | display: block; 150 | } 151 | 152 | input.toggle+label::after { 153 | content: "▸"; 154 | } 155 | 156 | input.toggle:checked+label::after { 157 | content: "▾"; 158 | } 159 | } 160 | 161 | // for RTL support 162 | body[dir="rtl"] .book-menu { 163 | input.toggle+label::after { 164 | content: "◂"; 165 | } 166 | 167 | input.toggle:checked+label::after { 168 | content: "▾"; 169 | } 170 | } 171 | 172 | .book-section-flat { 173 | margin: $padding-16 * 2 0; 174 | 175 | >a, 176 | >span, 177 | >label { 178 | font-weight: bolder; 179 | } 180 | 181 | >ul { 182 | padding-inline-start: 0; 183 | } 184 | } 185 | 186 | .book-page { 187 | min-width: $body-min-width; 188 | flex-grow: 1; 189 | padding: $padding-16; 190 | } 191 | 192 | .book-post { 193 | margin-bottom: $padding-16 * 3; 194 | } 195 | 196 | .book-header { 197 | display: none; 198 | margin-bottom: $padding-16; 199 | 200 | label { 201 | line-height: 0; 202 | } 203 | 204 | img.book-icon { 205 | height: 1.5em; 206 | width: 1.5em; 207 | } 208 | } 209 | 210 | .book-search { 211 | position: relative; 212 | margin: $padding-16 0; 213 | border-bottom: 1px solid transparent; 214 | 215 | input { 216 | width: 100%; 217 | padding: $padding-8; 218 | 219 | border: 0; 220 | border-radius: $border-radius; 221 | 222 | background: var(--gray-100); 223 | color: var(--body-font-color); 224 | 225 | &:required+.book-search-spinner { 226 | display: block; 227 | } 228 | } 229 | 230 | .book-search-spinner { 231 | position: absolute; 232 | top: 0; 233 | margin: $padding-8; 234 | margin-inline-start: calc(100% - #{$padding-16 + $padding-8}); 235 | 236 | width: $padding-16; 237 | height: $padding-16; 238 | 239 | border: $padding-1 solid transparent; 240 | border-top-color: var(--body-font-color); 241 | border-radius: 50%; 242 | 243 | @include spin(1s); 244 | } 245 | 246 | small { 247 | opacity: 0.5; 248 | } 249 | } 250 | 251 | .book-toc { 252 | flex: 0 0 $toc-width; 253 | font-size: $font-size-12; 254 | 255 | .book-toc-content { 256 | width: $toc-width; 257 | padding: $padding-16; 258 | 259 | @include fixed; 260 | } 261 | 262 | img { 263 | height: 1em; 264 | width: 1em; 265 | } 266 | 267 | nav>ul>li:first-child { 268 | margin-top: 0; 269 | } 270 | } 271 | 272 | .book-footer { 273 | padding-top: $padding-16; 274 | font-size: $font-size-14; 275 | 276 | img { 277 | height: 1em; 278 | width: 1em; 279 | margin-inline-end: $padding-8; 280 | } 281 | } 282 | 283 | .book-comments { 284 | margin-top: $padding-16; 285 | } 286 | 287 | .book-languages { 288 | margin-block-end: $padding-16 * 2; 289 | 290 | .book-icon { 291 | height: 1em; 292 | width: 1em; 293 | margin-inline-end: .5em; 294 | } 295 | 296 | ul { 297 | padding-inline-start: 1.5em; 298 | } 299 | } 300 | 301 | // Responsive styles 302 | .book-menu-content, 303 | .book-toc-content, 304 | .book-page, 305 | .book-header aside, 306 | .markdown { 307 | transition: 0.2s ease-in-out; 308 | transition-property: transform, margin, opacity, visibility; 309 | will-change: transform, margin, opacity; 310 | } 311 | 312 | @media screen and (max-width: $mobile-breakpoint) { 313 | 314 | #menu-control, 315 | #toc-control { 316 | display: inline; 317 | } 318 | 319 | .book-menu { 320 | visibility: hidden; 321 | margin-inline-start: -$menu-width; 322 | font-size: $font-size-base; 323 | z-index: 1; 324 | } 325 | 326 | .book-toc { 327 | display: none; 328 | } 329 | 330 | .book-header { 331 | display: block; 332 | } 333 | 334 | #menu-control:focus~main label[for="menu-control"] { 335 | @include outline; 336 | } 337 | 338 | #menu-control:checked~main { 339 | .book-menu { 340 | visibility: initial; 341 | } 342 | 343 | .book-menu .book-menu-content { 344 | transform: translateX($menu-width); 345 | box-shadow: 0 0 $padding-8 rgba(0, 0, 0, 0.1); 346 | } 347 | 348 | .book-page { 349 | opacity: 0.25; 350 | } 351 | 352 | .book-menu-overlay { 353 | display: block; 354 | position: absolute; 355 | top: 0; 356 | bottom: 0; 357 | left: 0; 358 | right: 0; 359 | } 360 | } 361 | 362 | #toc-control:focus~main label[for="toc-control"] { 363 | @include outline; 364 | } 365 | 366 | #toc-control:checked~main { 367 | .book-header aside { 368 | display: block; 369 | } 370 | } 371 | 372 | // for RTL support 373 | body[dir="rtl"] #menu-control:checked~main { 374 | .book-menu .book-menu-content { 375 | transform: translateX(-$menu-width); 376 | } 377 | } 378 | } 379 | 380 | // Extra space for big screens 381 | @media screen and (min-width: $container-max-width) { 382 | 383 | .book-page, 384 | .book-menu .book-menu-content, 385 | .book-toc .book-toc-content { 386 | padding: $padding-16 * 2 $padding-16; 387 | } 388 | } 389 | 390 | 391 | // nice preview 392 | .profile-hover { 393 | display: none; 394 | position: absolute; 395 | z-index: 99; 396 | margin-left: 10px; 397 | border: 1px solid #333; 398 | background: #eee; 399 | width: 300px; 400 | text-align: center; 401 | } 402 | 403 | a:hover+div { 404 | display: block; 405 | float: right; 406 | } -------------------------------------------------------------------------------- /content/docs/zkdocs/protocol-primitives/shamir.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 9 3 | bookFlatSection: true 4 | title: "Shamir's Secret Sharing Scheme" 5 | summary: "An overview of Shamir's Secret Sharing scheme and potential security pitfalls." 6 | references: ["shamir"] 7 | --- 8 | # Shamir’s Secret Sharing Scheme 9 | [Shamir's Secret Sharing Scheme](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing) is a way of splitting a secret value $S$ into $n$ "pieces" (or "shares") in such a way that any combination of $k$ pieces can be used to recover $S$, but any $k-1$ or fewer pieces provide _no_ information about $S$. 10 | 11 | ## Overview of Secret Sharing 12 | 13 | Shamir's Secret Sharing Scheme relies on a very useful property of polynomials: any degree-$k$ polynomial can be uniquely identified by _any_ set of $k+1$ distinct points. Two points define a line; three points define a parabola. However, with fewer than $k+1$ distinct points, no further information can be gained about the polynomial. 14 | 15 | This leads directly to Shamir's approach: encode a secret $S$ into a polynomial over a finite field, and distribute points on the polynomial as shares. 16 | 17 | ### Splitting $S$ 18 | 19 | Given a secret $S$, a number of desired shares $n$, and a threshold $k$, splitting $S$ comes down to two steps: 20 | - encode $S$ into a secret polynomial $f\left(x\right)$ of degree $k-1$ over a finite field $\field{p}$ 21 | - generate distinct shares $\left(x_{i}, f(x_i)\right)$ 22 | 23 | #### Encoding $S$ in a Polynomial 24 | 25 | Shamir proposed a straightforward method for encoding secrets into polynomials: set the constant term of a random polynomial to the secret $S$, and select all other coefficients uniformly at random. For a degree-$(k-1)$ polynomial, there would be $k-1$ random coefficients $r_i$, and the constant coefficient of $S$: 26 | $$f(x) = S + r_1 x + \ldots + r_{k-1} x^{k-1} \enspace.$$ 27 | 28 | {{< hint info>}} 29 | **Example:** We want to share our secret number 42 with three players so that any two of them can recover it. We define the degree-1 polynomial over $\field{73}$ as 30 | $$f(x) = 42 + 13 \cdot x \enspace,$$ 31 | where 13 was randomly sampled over $\field{73}$. We evaluate the polynomial at different points obtaining the shares $(x_i, f(x_i))$. Then, we can share 1 point of the coefficient to the three players, each getting one of $(1, 55), (2, 68), (3, 8)$. Since the polynomial is a line, any two of them could meet and recover the secret value 42! 32 | {{< /hint >}} 33 | 34 | This choice has the advantage of relative simplicity; there is no need to use oddball sampling techniques to select the coefficients of $f\left(x\right)$. 35 | 36 | ##### A Note on Selecting $p$ 37 | In the _general_ case, the specific prime $p$ does not matter much. Shamir's original paper proposed using 16-bit primes (the largest of which would be $p=2^{16}-15=65521$) for performance reasons. By limiting intermediate results to 32 bits, multi-precision arithmetic routines could be avoided on any 32-bit processor. Large secrets could be broken into blocks of 16 bits or less and shared with distinct polynomials. One limitation imposed by such a small $p$ is that only about 65000 distinct shares can be generated. 38 | 39 | In practice, $p$ should be reasonably large. Breaking $S$ into multiple parts introduces complexity and opportunities for malicious actors. Also, in some verifiable secret sharing schemes, a large $p$ is needed to prevent discrete log attacks. 40 | 41 | #### Generating the Shares 42 | 43 | Shares $s_{1},s_{2},\ldots,s_{n}$ of $S$ are ordered pairs $\left(x_{i}, f\left(x_{i}\right)\right)$. The $x_{i}$ values can be picked in several ways, but a counter starting in 1 is the most common method. 44 | 45 | ### Recovering $S$ 46 | 47 | The most common and direct method of recovering $S$ from the shares $s_{1},\ldots,s_{k}$ is to evaluate $f\left(0\right)=S$ using Lagrange interpolation. It allows computing $f\left(t\right)$ for any $t\in\field{p}$ using the formula below: 48 | 49 | $$f\left(t\right) = \displaystyle\sum_{j=1}^{k}{y_{j}\left(\displaystyle\prod_{\begin{smallmatrix}1\leq m\leq k\\\\ m\neq j\end{smallmatrix}}{\frac{t-x_m}{x_j - x_m}}\right)}$$ 50 | 51 | The $t=0$ case slightly simplifies the product. Each product term can also be precomputed since it only depends on the $x$-coordinate of the shares that can be publicly known. 52 | $$f\left(0\right) = \displaystyle\sum_{j=1}^{k}{y_{j}\left(\displaystyle\prod_{\begin{smallmatrix}1\leq m\leq k\\\\ m\neq j\end{smallmatrix}}{\frac{x_m}{x_m - x_j}}\right)}$$ 53 | 54 | The Lagrange interpolating polynomial is popular because it's fast enough for several use cases and relatively simple to implement. 55 | 56 | ## The Zero Share Problem 57 | 58 | ### How Shares are Generated 59 | 60 | As mentioned above, there are several ways to select the $x_{i}$ values during the share-generation phase of the algorithm. 61 | 62 | The most common approach, and the one we recommend, is to use a counter, setting $x_{i}=i$ for $i=1,2,\ldots,n$. This has the advantage of simplicity and speed. No user-generated inputs are necessary, and evaluating $f\left(x\right)$ when $x$ is small can be faster than for arbitrary-selected values in the field. 63 | 64 | Another approach is to use unique values associated with shareholders, such as userid values from a database, or users' provided values. 65 | 66 | Finally, some implementations select $x_{i}$ by selecting them randomly from $\field{p}$. 67 | 68 | ### What Can Go Wrong? 69 | 70 | * **Zero share problem:** If it is possible to wind up with $x_{i}=0$ for some $i$, the corresponding share is $\left(0, S\right)$, revealing $S$ directly to the $i$-th shareholder. This is not a hypothetical attack; several instances of this problem have been spotted in the wild. Implementations must guarantee that all $x_i$ are modularly nonzero. 71 | * **Non-unique shares:** The $x_i$ for each value must be modularly unique; when users reconstruct the secret from a share, they need to compute $\frac{x_m}{x_m-x_j}$. If the polynomial is evaluated modulo $q$ and if $x_m\equiv x_j \pmod{q}$, the modular inverse of $(x_m-x_j)$ does not exist and the protocol does not work. Some applications do not check if this modular inverse exists and usually do not handle this gracefully. 72 | 73 | ### How Things Go Wrong 74 | 75 | - **Counter-based shares:** One of the most common control structures in programming is a loop with a starting index of `i = 0`. The line `for(int i = 0; i < n; i++)` is near-idiomatic in C; `for i in range(n):` is an idiom in Python. It's easy to fall into an old pattern and fail to update these to the correct `for(int i = 1; i <= n; i++)` and `for i in range(1, n + 1):`, respectively. An initial draft of this page _included this very error_ in the "correct" C loop! This common error is enough to destroy the security of the system entirely. 76 | 77 | - **Userid-based shares:** Trusting unique user identifiers is problematic, too. A user can have a userid of 0 in plenty of systems. Trusting user-supplied values in security-critical contexts is never a good idea. Even if you compare the userid with 0, you might fail to do it correctly: since the polynomial evaluates over the finite field $\field{p}$, you need to check if it is 0 in $\field{p}$. In the case of the integers modulo a prime number, you must check that the userid is *modularly* different from zero. 78 | Even transforming user inputs can be problematic if you're not careful. For instance, given a user input $n$, a program may try to avoid this issue by taking the $x$-coordinate of $n\cdot G$, where $G$ is a generator of an elliptic curve group. However, if $n$ is 0, the resulting point is the "point at infinity". With some curve parameterizations, the point at infinity is represented as $\left(0,1\right)$. 79 | 80 | - **Random shares:** Selecting random values seems safe– in theory, the probability of selecting 0 from $\field{p}$ is $\frac{1}{p}$. But winding up with a zero share is significantly more likely than that. Consider the case where a program generates random numbers by reading from `/dev/random`. For Linux kernels before version 5.6, it is possible for `/dev/random` to block when the "entropy runs out". Since Linux 5.6, `/dev/random` can still block if the PRNG has not been initialized. If a programmer does not check the return value of the `read` function, then depending on how the destination buffer is allocated, the destination buffer can be left in a zeroed state, leading to a zero share. 81 | 82 | --------------------------------------------------------------------------------