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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
//! # Primitive types
//!
//! For more detail on these types and the implementation of these functions, refer to existing
//! documentation and specification for the Mina protocol.
//!
//! Note: The implementations for these types and functions are not included in this reference
//! implementation. Implementors must provide their own implementations in accordance with existing
//! specifications, or as updated by future specifications and proposals.

/// A element of the (prime) finite field of order
/// `28948022309329048855892746252171976963363056481941647379679742748393362948097`.
///
/// This field is the base field for [Pallas curve points](Pallas) and the scalar field for [Vesta
/// curve points](Vesta).
#[derive(Copy, Clone)]
pub struct Fp {/* Implementation elided */}

impl Fp {
    /// The 'zero' element of the finite field
    pub fn zero() -> Fp {
        panic!("Implementation elided")
    }
}

/// A element of the (prime) finite field of order
/// `28948022309329048855892746252171976963363056481941560715954676764349967630337`.
///
/// This field is the base field for [Vesta curve points](Vesta) and the scalar field for [Pallas
/// curve points](Pallas).
#[derive(Copy, Clone)]
pub struct Fq {/* Implementation elided */}

/// A point on the 'Vesta' elliptic curve.
///
/// Points on this curve are defined by the equation
/// `y^2 = x^3 + a*x + b` with the constants `a = 0` and `b = 5`,
/// where `x` and `y` are elements of the finite field [`Fq`].
///
/// Points on the Vesta curve form a prime group of order
/// `28948022309329048855892746252171976963363056481941647379679742748393362948097`
/// under the standard [elliptic curve
/// addition](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law) operation.
#[derive(Copy, Clone)]
pub struct Vesta {/* Implementation elided */}

impl Vesta {
    /// The elliptic curve point used as the [generator](https://en.wikipedia.org/wiki/Cyclic_group) for the group.
    ///
    /// This is the constant point defined by
    /// `x = 1, y = 11426906929455361843568202299992114520848200991084027513389447476559454104162`
    pub fn one() -> Vesta {
        panic!("Implementation elided")
    }

    /// The standard [elliptic curve
    /// addition](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law) group operation on the Vesta curve.
    #[allow(unused)]
    pub fn add(a: Vesta, b: Vesta) -> Vesta {
        panic!("Implementation elided")
    }

    /// The standard elliptic curve scaling operation.
    ///
    /// `scale(a, s) = add(add(...add(a, a), ..., a), a)`, where `add` is applied `s` times.
    ///
    /// Note that `s` is an element of the finite field of the same order as the group formed under
    /// `add`.
    #[allow(unused)]
    pub fn scale(a: Vesta, s: Fp) -> Vesta {
        panic!("Implementation elided")
    }
}

/// A point on the 'Pallas' elliptic curve.
///
/// Points on this curve are defined by the equation
/// `y^2 = x^3 + a*x + b` with the constants `a = 0` and `b = 5`,
/// where `x` and `y` are elements of the finite field [`Fp`].
///
/// Points on the Pallas curve form a prime group of order
/// `28948022309329048855892746252171976963363056481941560715954676764349967630337`
/// under the standard [elliptic curve
/// addition](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law) operation.
#[derive(Copy, Clone)]
pub struct Pallas {/* Implementation elided */}

impl Pallas {
    /// The elliptic curve point used as the [generator](https://en.wikipedia.org/wiki/Cyclic_group) for the group.
    ///
    /// This is the constant point defined by
    /// `x = 1, y = 12418654782883325593414442427049395787963493412651469444558597405572177144507`
    pub fn one() -> Pallas {
        panic!("Implementation elided")
    }

    /// The standard [elliptic curve
    /// addition](https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law) group operation on the pallas curve.
    #[allow(unused)]
    pub fn add(a: Pallas, b: Pallas) -> Pallas {
        panic!("Implementation elided")
    }

    /// The standard elliptic curve scaling operation.
    ///
    /// `scale(a, s) = add(add(...add(a, a), ..., a), a)`, where `add` is applied `s` times.
    ///
    /// Note that `s` is an element of the finite field of the same order as the group formed under
    /// `add`.
    #[allow(unused)]
    pub fn scale(a: Pallas, s: Fq) -> Pallas {
        panic!("Implementation elided")
    }
}

/// The type of hash inputs used in the Mina protocol.
#[derive(Copy, Clone)]
pub struct HashInput {/* Implementation elided */}

impl HashInput {
    /// Construct a hash input with no contents.
    pub fn empty() -> HashInput {
        panic!("Implementation elided")
    }

    /// Add an `Fp` field element to the given `HashInput`, using the default algorithm in the Mina
    /// protocol.
    #[allow(unused)]
    pub fn add_field(current: &mut HashInput, x: Fp) {
        panic!("Implementation elided")
    }

    /// Add an `Fp` field element to the given `HashInput`, using the default algorithm in the Mina
    /// protocol.
    ///
    /// `add_field(hash_input, x, n)` must not be used if `x >= 2^n`.
    /// `add_field(hash_input, x, n)` is invalid if `n >= 254`, the size in bits of `Fp`.
    #[allow(unused)]
    pub fn add_field_restricted(current: &mut HashInput, x: Fp, n: usize) {
        panic!("Implementation elided")
    }
}

pub struct HashPrefixState([Fp; 3]);

impl HashPrefixState {
    /// The hash prefix state for events
    /// TODO: Inline the constant here
    pub fn event() -> HashPrefixState {
        panic!("TODO")
    }

    /// The hash prefix state for a list of event hashes
    /// TODO: Inline the constant here
    pub fn events_list() -> HashPrefixState {
        panic!("TODO")
    }

    /// The hash prefix state for sequence events
    /// TODO: Inline the constant here
    pub fn sequence_event() -> HashPrefixState {
        panic!("TODO")
    }

    /// The hash prefix state for a list of sequence event hashes
    /// TODO: Inline the constant here
    pub fn sequence_events_list() -> HashPrefixState {
        panic!("TODO")
    }

    /// The hash prefix state for the sequence state
    /// TODO: Inline the constant here
    pub fn sequence_state() -> HashPrefixState {
        panic!("TODO")
    }
}

/// The type of hashes used in the Mina protocol.
pub type Hash = Fp;

impl Hash {
    /// Compute a hash from a hash input and a prefix state.
    #[allow(unused)]
    pub fn compute_hash(prefix_state: HashPrefixState, input: HashInput) -> Hash {
        panic!("Implementation elided")
    }

    /// The 'empty' receipt-chain hash, as defined in the Mina protocol constants.
    pub fn empty_receipt_chain_hash() -> Hash {
        panic!("Implementation elided")
    }

    /// The 'empty' events hash.
    /// TODO: Inline the constant here
    pub fn empty_events() -> Hash {
        panic!("TODO")
    }

    /// The 'empty' sequence events hash.
    /// TODO: Inline the constant here
    pub fn empty_sequence_events() -> Hash {
        panic!("TODO")
    }

    /// The 'empty' sequence state hash.
    /// TODO: Inline the constant here
    pub fn empty_sequence_state() -> Hash {
        panic!("TODO")
    }
}

/// The type of state hashes used in the Mina protocol.
pub type StateHash = Hash;

impl StateHash {
    /// The 'empty' state hash, as defined in the Mina protocol constants.
    pub fn invalid_hash() -> StateHash {
        panic!("Implementation elided")
    }
}

/// The type of signatures used in the Mina protocol.
#[derive(Copy, Clone)]
pub struct Signature {/* Implementation elided */}

impl Signature {
    #[allow(unused)]
    pub fn verify(signature: Signature, public_key: PublicKey, hash_input: HashInput) -> bool {
        panic!("Implementation elided")
    }
}

/// The type of private keys used in the Mina protocol.
pub type PrivateKey = Fp;

impl PrivateKey {
    /// Compute the public key for the given private key.
    #[allow(unused)]
    pub fn public_key(private_key: PrivateKey) -> PublicKey {
        panic!("Implementation elided")
    }
}

/// The type of public keys used in the Mina protocol.
pub type PublicKey = Pallas;

impl PublicKey {
    /// Compute the 'compressed' representation of a public key.
    #[allow(unused)]
    pub fn compress(public_key: PublicKey) -> CompressedPublicKey {
        panic!("Implementation elided")
    }
}

/// A 'compressed' representation of the public keys used in the Mina protocol.
///
/// This representation maps to a public key
#[derive(Copy, Clone)]
pub struct CompressedPublicKey {/* Implementation elided */}

impl CompressedPublicKey {
    /// Check that a 'compressed' public key corresponds to a valid curve point, and thus may be
    /// decompressed.
    #[allow(unused)]
    pub fn is_valid(public_key: CompressedPublicKey) -> bool {
        panic!("Implementation elided")
    }

    /// Compute the public key corresponding to this 'compressed' representation.
    ///
    /// `decompress(pk) = None` if and only if `is_valid(pk) = false`.
    #[allow(unused)]
    pub fn decompress(public_key: CompressedPublicKey) -> Option<PublicKey> {
        panic!("Implementation elided")
    }

    /// Compute the public key corresponding to this 'compressed' representation.
    ///
    /// `decompress_exn(pk)` must raise an exception if `is_valid(pk) = false`.
    #[allow(unused)]
    pub fn decompress_exn(public_key: CompressedPublicKey) -> PublicKey {
        panic!("Implementation elided")
    }

    /// The 'empty' public key.
    ///
    /// This public key is associated with unused accounts in the ledger. This public key is
    /// invalid, `is_valid(empty())` must return `false`.
    pub fn empty() -> CompressedPublicKey {
        panic!("Implementation elided")
    }
}