forked from IntersectMBO/cardano-ledger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
crypto-primitives.tex
267 lines (244 loc) · 10.6 KB
/
crypto-primitives.tex
1
2
3
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
\section{Cryptographic primitives}
\label{sec:crypto-primitives-shelley}
Figure~\ref{fig:crypto-defs-shelley} introduces the cryptographic abstractions used in
this document. We begin by listing the abstract types, which are meant to
represent the corresponding concepts in cryptography.
Their exact
implementation remains open to interpretation and we do not rely on
any additional properties of public key cryptography that are not explicitly stated
in this document. The types and rules we give here are needed in
order to guarantee certain security properties of the delegation process, which
we discuss later.
The cryptographic concepts required for the formal definition of witnessing
include public-private key pairs, one-way functions, signatures and
multi-signature scripts. The constraint we introduce states that a signature of
some data signed with a (private) key is only correct whenever we can verify it
using the corresponding public key.
Abstract data types in this paper are essentially placeholders with names
indicating the data types they are meant to represent in an implementation.
Derived types are made up of data structures (i.e.~products, lists, finite
maps, etc.) built from abstract types. The underlying structure of a data type
is implementation-dependent and furthermore, the way the data is stored on
physical storage can vary as well.
Serialization is a physical manifestation of data on a given storage device.
In this document, the properties and rules we state involving serialization are
assumed to hold true independently of the storage medium and style of data
organization chosen for an implementation.
The type $\Ser$ denotes the serialized representation of a term of any serializable
type.
\begin{figure}[htb]
\emph{Abstract types}
%
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\var{sk} & \SKey & \text{private signing key}\\
\var{vk} & \VKey & \text{public verifying key}\\
\var{hk} & \KeyHash & \text{hash of a key}\\
\sigma & \Sig & \text{signature}\\
\var{d} & \Ser & \text{data}\\
\var{script} & \Script & \text{multi-signature script} \\
\var{hs} & \HashScr & \text{hash of a script}
\end{array}
\end{equation*}
\emph{Derived types}
\begin{equation*}
\begin{array}{r@{~\in~}lr}
(sk, vk) & \KeyPair & \text{signing-verifying key pairs}
\end{array}
\end{equation*}
\emph{Abstract functions}
%
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\hashKey{} & \VKey \to \KeyHash
& \text{hash a verification key} \\
%
\fun{verify} & \powerset{\left(\VKey \times \Ser \times \Sig\right)}
& \text{verification relation}\\
%
\fun{sign} & \SKey \to \Ser \to \Sig
& \text{signing function}\\
\fun{hashScript} & \Script \to \HashScr & \text{hash a serialized script}
\end{array}
\end{equation*}
\emph{Constraints}
\begin{align*}
& \forall (sk, vk) \in \KeyPair,~ d \in \Ser,~ \sigma \in \Sig \cdot
\sign{sk}{d} = \sigma \implies (vk, d, \sigma) \in \fun{verify}
\end{align*}
\emph{Notation for serialized and verified data}
\begin{align*}
& \serialised{x} ~\in \Ser & \text{serialised representation of } x\\
& \mathcal{V}_{\var{vk}}{\serialised{d}}_{\sigma} = \verify{vk}{d}{\sigma}
& \text{shorthand notation for } \fun{verify}
\end{align*}
\caption{Cryptographic definitions}
\label{fig:crypto-defs-shelley}
\end{figure}
When we get to the blockchain layer validation, we will use
key evolving signatures (KES).
This is another asymmetric key cryptographic scheme, also relying on
the use of public and private key pairs.
These signature schemes provide forward cryptographic security, meaning that a
compromised key does not make it easier for an adversary to forge a signature that
allegedly had been signed in the past.
Figure~\ref{fig:kes-defs-shelley} introduces the additional cryptographic abstractions
needed for KES.
In KES, the public verification key stays constant, but the
corresponding private key evolves incrementally. For this reason, KES
signing keys are indexed by integers representing the step in the key's
evolution. This evolution step parameter is also an additional parameter needed
for the signing (denoted by $\fun{sign_{ev}}$) and verification
(denoted by $\fun{verify_{ev}}$) functions.
Since the private key evolves incrementally in a KES scheme, the ledger rules
require the pool operators to evolve their keys every time a certain number of
slots have passed, as determined by the global constant $\SlotsPerKESPeriod$.
\begin{figure}[htb]
\emph{Abstract types}
%
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\var{sk} & \N \to \SKeyEv & \text{private signing keys}\\
\var{vk} & \VKeyEv & \text{public verifying key}\\
\end{array}
\end{equation*}
\emph{Notation for evolved signing key}
\begin{align*}
& \var{sk_n} = \var{sk}~n & n\text{-th evolution of }sk
\end{align*}
\emph{Derived types}
\begin{equation*}
\begin{array}{r@{~\in~}lr}
(sk_n, vk) & \KeyPairEv & \text{signing-verifying key pairs}
\end{array}
\end{equation*}
\emph{Abstract functions}
%
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\fun{verify_{ev}} & \powerset{\left(\VKey \times \N \times \Ser \times \Sig\right)}
& \text{verification relation}\\
%
\fun{sign_{ev}} & (\N \to \SKeyEv) \to \N \to \Ser \to \Sig
& \text{signing function}\\
\end{array}
\end{equation*}
\emph{Constraints}
\begin{align*}
& \forall n\in\N, (sk_n, vk) \in \KeyPairEv, ~ d \in \Ser,~ \sigma \in \Sig \cdot \\
& ~~~~~~~~\fun{sign_{ev}}~{sk}~{n}~{d} = \sigma \implies \verifyEv{vk}{n}{d}{\sigma}
\end{align*}
\emph{Notation for verified KES data}
\begin{align*}
& \mathcal{V}^{\mathsf{KES}}_{\var{vk}}{\serialised{d}}_{\sigma}^n
= \verifyEv{vk}{n}{d}{\sigma}
& \text{shorthand notation for } \fun{verify_{ev}}
\end{align*}
\caption{KES Cryptographic definitions}
\label{fig:kes-defs-shelley}
\end{figure}
Figure~\ref{fig:types-msig} shows the types for multi-signature
schemes. Multi-signatures effectively specify one or more combinations of
cryptographic signatures which are considered valid. This is realized in a
native way via a script-like DSL which allows for defining terms that can be
evaluated. Multi-signature scripts is the only type of script (for any
purpose, including output-locking) that exist in Shelley.
The terms form a tree like structure and are evaluated via the
\fun{evalMultiSigScript} function. The parameters are a script and a set of key
hashes. The function returns $\mathsf{True}$ when the supplied key hashes are
a valid combination for the script, otherwise it returns $\mathsf{False}$.
The following are the four constructors that make up the multisignature script
scheme:
\begin{itemize}
\item[$\type{RequireSig}$] ~:~ the signature of a key with a specific
hash is required;
\item[$\type{RequireAllOf}$] ~:~signatures of all of the keys that hash to the
values specified in the given list are required;
\item[$\type{RequireAnyOf}$] ~:~a single signature is required, by a key hashing
to one of the given values in the list (this constructor is redundant and can
be expressed using $\type{RequireMOf}$);
\item[$\type{RequireMOf}$]~:~ $m$ of the keys with the hashes specified in the list
are required to sign
\end{itemize}
\begin{figure*}[hbt]
\emph{MultiSig Type}
\begin{equation*}
\begin{array}{rll}
\MSig & \subseteq & \Script \\
\\~\\
\var{msig}\in\MSig & = & \type{RequireSig}~\KeyHash\\
& \uniondistinct &
\type{RequireAllOf}~[\Script] \\
& \uniondistinct&
\type{RequireAnyOf}~[\Script] \\
& \uniondistinct&
\type{RequireMOf}~\N~[\Script]
\end{array}
\end{equation*}
\emph{Functions}
\begin{align*}
\fun{evalMultiSigScript} & \in\MSig\to\powerset\KeyHash\to\Bool & \\
\fun{evalMultiSigScript} & ~(\type{RequireSig}~hk)~\var{vhks} = hk \in vhks \\
\fun{evalMultiSigScript} & ~(\type{RequireAllOf}~ts)~\var{vhks} =
\forall t \in ts: \fun{evalMultiSigScript}~t~vhks\\
\fun{evalMultiSigScript} & ~(\type{RequireAnyOf}~ts)~\var{vhks} =
\exists t \in ts: \fun{evalMultiSigScript}~t~vhks\\
\fun{evalMultiSigScript} & ~(\type{RequireMOf}~m~ts)~\var{vhks} = \\
& m \leq \Sigma
\left(
[\textrm{if}~(\fun{evalMultiSigScript}~\var{t}~\var{vhks})~
\textrm{then}~1~\textrm{else}~0\vert t \leftarrow ts]
\right)
\end{align*}
\caption{Multi-signature via Native Scripts}
\label{fig:types-msig}
\end{figure*}
%\subsection{Verifiable Random Functions (VRF)}
%\label{sec:defs-vrf}
Figure~\ref{fig:defs-vrf} shows the cryptographic abstractions needed for Verifiable Random Functions (VRF). VRFs allow key-pair owners, $(sk, vk)\in \KeyPair$, to evaluate a pseudorandom function in a provable way given a randomness seed. Any party with access to the verification key, $vk$, the randomness seed, the proof and the generated randomness can indeed verify that the value is pseudorandom.
\begin{figure}[htb]
%
\emph{Abstract types}
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\var{seed} & \Seed & \text{seed for pseudo-random number generator}\\
\var{prf} & \Proof & \text{VRF proof}\\
\end{array}
\end{equation*}
%
\emph{Abstract functions ($T$ an arbitrary type)}
%
\begin{equation*}
\begin{array}{r@{~\in~}lr}
\seedOp & \Seed \to \Seed \to \Seed & \text{binary seed operation} \\
\vrf{\T}{}{} & \SKey \to \Seed \to \T\times\Proof
& \text{verifiable random function} \\
%
\verifyVrf{\T}{}{}{} & \VKey \to \Seed \to \Proof\times\T \to \Bool
& \text{verify vrf proof} \\
%
\end{array}
\end{equation*}
%
\emph{Derived Types}
\begin{align*}
\PoolDistr = \KeyHash_{pool} \mapsto \left([0, 1]\times\KeyHash_{vrf}\right)
\text{ \hspace{1cm}stake pool distribution}
\end{align*}
%
\emph{Constraints}
\begin{align*}
& \forall (sk, vk) \in \KeyPair,~ seed \in \Seed,~
\verifyVrf{T}{vk}{seed}{\left(\vrf{T}{sk}{seed}\right)}
\end{align*}
%
\emph{Constants}
\begin{align*}
& 0_{seed} \in \Seed & \text{neutral seed element} \\
& \Seedl \in \Seed & \text{leader seed constant} \\
& \Seede \in \Seed & \text{nonce seed constant}\\
\end{align*}
\caption{VRF definitions}
\label{fig:defs-vrf}
\end{figure}
\clearpage