https://gitlab.com/tezos/tezos
Tip revision: 2905bdc373ff20f3b84c619851c0b293c4ecb67b authored by saroupille on 22 March 2024, 12:42:04 UTC
Tezt_cloud: Initial commit introducing the library
Tezt_cloud: Initial commit introducing the library
Tip revision: 2905bdc
types.ml
(*****************************************************************************)
(* *)
(* MIT License *)
(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
module U = Utils
open Plompiler
module HashPV = Anemoi128
module MerklePV = Gadget.Merkle (HashPV)
module SchnorrPV = Plompiler.Schnorr (HashPV)
module Curve = Mec.Curve.Jubjub.AffineEdwards
open Constants
module Bounded = Bounded.Make (Bound)
module P = struct
module Schnorr = SchnorrPV.P
module Merkle = MerklePV.P
module Bounded = Bounded.P
type 'a ticket = {id : S.t; amount : 'a Bounded.t}
type tezos_pkh = bytes
type tezos_zkru = bytes
type account = {
pk : Schnorr.pk;
tez_balance : balance Bounded.t;
cnt : counter Bounded.t;
tickets_root : S.t;
}
type leaf = {pos : position Bounded.t; ticket : balance ticket}
module IMap = Map.Make (Int)
type state = {
(* account index*)
accounts : (account * leaf array * Merkle.tree) IMap.t;
accounts_tree : Merkle.tree;
(* First leaf of an empty account *)
next_position : int;
}
type proof = {path : Merkle.path; root : S.t}
type account_tree_el = {before : account; after : account; proof : proof}
type leaf_tree_el = {before : leaf; after : leaf; path : Merkle.path}
type tree_el = {account : account_tree_el; leaf : leaf_tree_el}
type header = {
op_code : op_code Bounded.t;
price : balance ticket;
l1_dst : tezos_pkh;
rollup_id : tezos_zkru;
}
type unsigned_transfer_payload = {
cnt : counter Bounded.t;
src : position Bounded.t;
dst : position Bounded.t;
amount : amount ticket;
fee : fee Bounded.t;
}
type transfer_payload = {
msg : unsigned_transfer_payload;
signature : Schnorr.signature;
}
type unsigned_transfer = {
header : header;
payload : unsigned_transfer_payload;
}
type transfer = {header : header; payload : transfer_payload}
type transfer_storage = {src : tree_el; dst : tree_el; valid : bool}
type unsigned_create_payload = {pk : Schnorr.pk; fee : fee Bounded.t}
type create_payload = {
msg : unsigned_create_payload;
signature : Schnorr.signature;
}
type unsigned_create = {header : header; payload : unsigned_create_payload}
type create = {header : header; payload : create_payload}
type create_storage = {dst : tree_el; next_empty : tree_el; valid : bool}
type credit_payload = {
cnt : counter Bounded.t;
dst : position Bounded.t;
amount : amount ticket;
}
type credit = {header : header; payload : credit_payload}
type credit_storage = {dst : tree_el; valid : bool}
type unsigned_debit_payload = {
cnt : counter Bounded.t;
src : position Bounded.t;
amount : amount ticket;
}
type debit_payload = {
msg : unsigned_debit_payload;
signature : Schnorr.signature;
}
type unsigned_debit = {header : header; payload : unsigned_debit_payload}
type debit = {header : header; payload : debit_payload}
type debit_storage = {src : tree_el; valid : bool}
type unsigned_tx =
| Transfer of unsigned_transfer
| Create of unsigned_create
| Credit of credit
| Debit of unsigned_debit
type tx =
| Transfer of transfer
| Create of create
| Credit of credit
| Debit of debit
type tx_storage =
| Transfer of transfer_storage
| Create of create_storage
| Credit of credit_storage
| Debit of debit_storage
module Dummy = struct
let cnt = Bounded.make ~bound:Bound.max_counter Z.zero
let fee = Bounded.make ~bound:Bound.max_fee Z.zero
let pos = Bounded.make ~bound:Bound.max_nb_leaves Z.zero
let amount = Bounded.make ~bound:Bound.max_amount Z.zero
let balance = Bounded.make ~bound:Bound.max_balance Z.zero
let ticket_amount = {id = S.zero; amount}
let ticket_balance = {id = S.zero; amount = balance}
let op_code = Bounded.make ~bound:Bound.max_op_code Z.zero
let root = Bls12_381.Fr.random ()
let sk = Curve.Scalar.random ()
let pk = Schnorr.neuterize sk
let tezos_pkh = Bytes.init 21 (fun i -> char_of_int i)
let tezos_zkru = Bytes.init 20 (fun _i -> char_of_int 0)
let signature =
let rand = Curve.Scalar.random () in
Schnorr.sign sk S.zero rand
let leaf : leaf = {pos; ticket = ticket_balance}
let account : account =
{pk; tez_balance = balance; cnt; tickets_root = root}
let proof depth : proof =
{path = List.init depth (fun _ -> (Bls12_381.Fr.random (), true)); root}
let account_tree_el : account_tree_el =
{
before = account;
after = account;
proof = proof Constants.accounts_depth;
}
let leaf_tree_el : leaf_tree_el =
{before = leaf; after = leaf; path = (proof Constants.tickets_depth).path}
let tree_el : tree_el = {account = account_tree_el; leaf = leaf_tree_el}
let header =
{
op_code;
price = ticket_balance;
l1_dst = tezos_pkh;
rollup_id = tezos_zkru;
}
let unsigned_transfer_payload =
{cnt; src = pos; dst = pos; amount = ticket_amount; fee}
let transfer_payload : transfer_payload =
{msg = unsigned_transfer_payload; signature}
let transfer : transfer = {header; payload = transfer_payload}
let transfer_storage : transfer_storage =
{src = tree_el; dst = tree_el; valid = true}
let unsigned_create_payload = {pk; fee}
let create_payload : create_payload =
{msg = unsigned_create_payload; signature}
let create : create = {header; payload = create_payload}
let create_storage : create_storage =
{dst = tree_el; next_empty = tree_el; valid = true}
let credit_payload = {cnt; dst = pos; amount = ticket_amount}
let credit : credit = {header; payload = credit_payload}
let credit_storage : credit_storage = {dst = tree_el; valid = true}
let unsgined_debit_payload = {cnt; src = pos; amount = ticket_amount}
let debit_payload : debit_payload =
{msg = unsgined_debit_payload; signature}
let debit : debit = {header; payload = debit_payload}
let debit_storage : debit_storage = {src = tree_el; valid = true}
end
end
module V (L : LIB) = struct
open L
module Schnorr = SchnorrPV.V (L)
module Merkle = MerklePV.V (L)
module Bounded_u = Bounded.V (L)
type curve_t_u = (scalar * scalar) repr
type curve_base_t_u = scalar repr
type curve_scalar_t_u = scalar repr
type 'a ticket_u = {id : scalar repr; amount : 'a Bounded_u.t}
type tezos_pkh_u = scalar repr
type tezos_zkru_u = scalar repr
type account_u = {
pk : Schnorr.pk repr;
tez_balance : balance Bounded_u.t;
cnt : counter Bounded_u.t;
tickets_root : scalar repr;
}
type leaf_u = {pos : position Bounded_u.t; ticket : balance ticket_u}
type proof_u = {path : Merkle.path; root : scalar repr}
type account_tree_el_u = {
before : account_u;
after : account_u;
proof : proof_u;
}
type leaf_tree_el_u = {before : leaf_u; after : leaf_u; path : Merkle.path}
type tree_el_u = {account : account_tree_el_u; leaf : leaf_tree_el_u}
type header_u = {
op_code : op_code Bounded_u.t;
price : balance ticket_u;
l1_dst : tezos_pkh_u;
rollup_id : tezos_zkru_u;
}
type unsigned_transfer_payload_u = {
cnt : counter Bounded_u.t;
src : position Bounded_u.t;
dst : position Bounded_u.t;
amount : amount ticket_u;
fee : fee Bounded_u.t;
}
type transfer_payload_u = {
msg : unsigned_transfer_payload_u;
signature : Schnorr.signature;
}
type transfer_u = {header : header_u; payload : transfer_payload_u}
type transfer_storage_u = {
src : tree_el_u;
dst : tree_el_u;
valid : bool repr;
}
type unsigned_create_payload_u = {pk : Schnorr.pk repr; fee : fee Bounded_u.t}
type create_payload_u = {
msg : unsigned_create_payload_u;
signature : Schnorr.signature;
}
type create_u = {header : header_u; payload : create_payload_u}
type create_storage_u = {
dst : tree_el_u;
next_empty : tree_el_u;
valid : bool repr;
}
type credit_payload_u = {
cnt : counter Bounded_u.t;
dst : position Bounded_u.t;
amount : amount ticket_u;
}
type credit_u = {header : header_u; payload : credit_payload_u}
type credit_storage_u = {dst : tree_el_u; valid : bool repr}
type unsigned_debit_payload_u = {
cnt : counter Bounded_u.t;
src : position Bounded_u.t;
amount : amount ticket_u;
}
type debit_payload_u = {
msg : unsigned_debit_payload_u;
signature : Schnorr.signature;
}
type debit_u = {header : header_u; payload : debit_payload_u}
type debit_storage_u = {src : tree_el_u; valid : bool repr}
end
module Encodings (L : LIB) = struct
module Bounded_e = Bounded.Encoding (L)
open P
open L
open V (L)
open L.Encodings
module Anemoi = Anemoi128.V
module Plompiler_Curve = JubjubEdwards (L)
module Plompiler_Hash = Anemoi (L)
open U
let s_of_int x = S.of_z (Z.of_int x)
let curve_base_t_encoding : (Curve.Base.t, curve_base_t_u, _) encoding =
conv
(fun r -> r)
(fun r -> r)
curve_base_to_s
curve_base_of_s
scalar_encoding
let curve_scalar_t_encoding : (Curve.Scalar.t, curve_scalar_t_u, _) encoding =
conv
(fun r -> r)
(fun r -> r)
curve_scalar_to_s
curve_scalar_of_s
scalar_encoding
let curve_t_encoding : (Curve.t, curve_t_u, _) encoding =
with_implicit_bool_check Plompiler_Curve.is_on_curve
@@ conv
(fun r -> of_pair r)
(fun (u, v) -> pair u v)
(fun c ->
( curve_base_to_s @@ Curve.get_u_coordinate c,
curve_base_to_s @@ Curve.get_v_coordinate c ))
(fun (u, v) ->
Curve.from_coordinates_exn
~u:(curve_base_of_s u)
~v:(curve_base_of_s v))
(obj2_encoding scalar_encoding scalar_encoding)
let balance_encoding ~safety =
Bounded_e.encoding ~safety Constants.Bound.max_balance
let amount_encoding ~safety =
Bounded_e.encoding ~safety Constants.Bound.max_amount
let fee_encoding ~safety = Bounded_e.encoding ~safety Constants.Bound.max_fee
let pos_encoding ~safety =
Bounded_e.encoding ~safety Constants.Bound.max_nb_leaves
let cnt_encoding ~safety =
Bounded_e.encoding ~safety Constants.Bound.max_counter
let op_code_encoding ~safety =
Bounded_e.encoding ~safety Constants.Bound.max_op_code
let tezos_pkh_encoding : (tezos_pkh, tezos_pkh_u, _) encoding =
conv
(fun pkhu -> pkhu)
(fun w -> w)
U.scalar_of_bytes
U.scalar_to_bytes
scalar_encoding
let tezos_zkru_encoding : (tezos_zkru, tezos_zkru_u, _) encoding =
conv
(fun zkru -> zkru)
(fun w -> w)
U.scalar_of_bytes
U.scalar_to_bytes
scalar_encoding
let ticket_encoding ~safety (bound : 'a Bound.t) :
('a ticket, 'a ticket_u, _) encoding =
conv
(fun {id; amount} -> (id, amount))
(fun (id, amount) -> {id; amount})
(fun ({id; amount} : 'a ticket) -> (id, amount))
(fun (id, amount) -> {id; amount})
(obj2_encoding scalar_encoding (Bounded_e.encoding ~safety bound))
let ticket_balance_encoding ~safety =
ticket_encoding ~safety Constants.Bound.max_balance
let ticket_amount_encoding ~safety =
ticket_encoding ~safety Constants.Bound.max_amount
let account_encoding : (account, account_u, _) encoding =
conv
(fun {pk; tez_balance; cnt; tickets_root} ->
(pk, (tez_balance, (cnt, tickets_root))))
(fun (pk, (tez_balance, (cnt, tickets_root))) ->
{pk; tez_balance; cnt; tickets_root})
(fun (acc : account) ->
(acc.pk, (acc.tez_balance, (acc.cnt, acc.tickets_root))))
(fun (pk, (tez_balance, (cnt, tickets_root))) ->
{pk; tez_balance; cnt; tickets_root})
(obj4_encoding
Schnorr.pk_encoding
(balance_encoding ~safety:NoCheck)
(cnt_encoding ~safety:NoCheck)
scalar_encoding)
let leaf_encoding : (leaf, leaf_u, _) encoding =
conv
(fun {pos; ticket} -> (pos, ticket))
(fun (pos, ticket) -> {pos; ticket})
(fun ({pos; ticket} : leaf) -> (pos, ticket))
(fun (pos, ticket) -> {pos; ticket})
(obj2_encoding
(pos_encoding ~safety:NoCheck)
(ticket_balance_encoding ~safety:NoCheck))
let proof_encoding : (proof, proof_u, _) encoding =
conv
(fun {path; root} -> (path, root))
(fun (path, root) -> {path; root})
(fun ({path; root} : proof) -> (path, root))
(fun (path, root) -> {path; root})
(obj2_encoding Merkle.path_encoding scalar_encoding)
let account_tree_el_encoding :
(account_tree_el, account_tree_el_u, _) encoding =
conv
(fun {before; after; proof} -> (before, (after, proof)))
(fun (before, (after, proof)) -> {before; after; proof})
(fun ({before; after; proof} : account_tree_el) ->
(before, (after, proof)))
(fun (before, (after, proof)) -> {before; after; proof})
(obj3_encoding account_encoding account_encoding proof_encoding)
let leaf_tree_el_encoding : (leaf_tree_el, leaf_tree_el_u, _) encoding =
conv
(fun {before; after; path} -> (before, (after, path)))
(fun (before, (after, path)) -> {before; after; path})
(fun ({before; after; path} : leaf_tree_el) -> (before, (after, path)))
(fun (before, (after, path)) -> {before; after; path})
(obj3_encoding leaf_encoding leaf_encoding Merkle.path_encoding)
let tree_el_encoding : (tree_el, tree_el_u, _) encoding =
conv
(fun {account; leaf} -> (account, leaf))
(fun (account, leaf) -> {account; leaf})
(fun ({account; leaf} : tree_el) -> (account, leaf))
(fun (account, leaf) -> {account; leaf})
(obj2_encoding account_tree_el_encoding leaf_tree_el_encoding)
let header_encoding ~safety : (header, header_u, _) encoding =
conv
(fun {op_code; price; l1_dst; rollup_id} ->
(op_code, (price, (l1_dst, rollup_id))))
(fun (op_code, (price, (l1_dst, rollup_id))) ->
{op_code; price; l1_dst; rollup_id})
(fun ({op_code; price; l1_dst; rollup_id} : header) ->
(op_code, (price, (l1_dst, rollup_id))))
(fun (op_code, (price, (l1_dst, rollup_id))) ->
{op_code; price; l1_dst; rollup_id})
(obj4_encoding
(op_code_encoding ~safety)
(ticket_balance_encoding ~safety)
tezos_pkh_encoding
tezos_zkru_encoding)
let unsigned_transfer_payload_encoding ~safety :
(unsigned_transfer_payload, unsigned_transfer_payload_u, _) encoding =
conv
(fun (tx : unsigned_transfer_payload_u) ->
(tx.cnt, (tx.src, (tx.dst, (tx.amount, tx.fee)))))
(fun (cnt, (src, (dst, (amount, fee)))) -> {cnt; src; dst; amount; fee})
(fun (tx : unsigned_transfer_payload) ->
(tx.cnt, (tx.src, (tx.dst, (tx.amount, tx.fee)))))
(fun (cnt, (src, (dst, (amount, fee)))) -> {cnt; src; dst; amount; fee})
(obj5_encoding
(cnt_encoding ~safety)
(pos_encoding ~safety)
(pos_encoding ~safety)
(ticket_amount_encoding ~safety)
(fee_encoding ~safety))
let transfer_payload_encoding ~safety :
(transfer_payload, transfer_payload_u, _) encoding =
conv
(fun ({msg; signature} : transfer_payload_u) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(fun ({msg; signature} : transfer_payload) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(obj2_encoding
(unsigned_transfer_payload_encoding ~safety)
Schnorr.signature_encoding)
let transfer_encoding ~safety : (transfer, transfer_u, _) encoding =
conv
(fun (tx : transfer_u) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(fun (tx : transfer) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(obj2_encoding
(header_encoding ~safety)
(transfer_payload_encoding ~safety))
let transfer_storage_encoding :
(transfer_storage, transfer_storage_u, _) encoding =
conv
(fun (tx : transfer_storage_u) -> (tx.src, (tx.dst, tx.valid)))
(fun (src, (dst, valid)) -> {src; dst; valid})
(fun (tx : transfer_storage) -> (tx.src, (tx.dst, tx.valid)))
(fun (src, (dst, valid)) -> {src; dst; valid})
(obj3_encoding tree_el_encoding tree_el_encoding bool_encoding)
let unsigned_create_payload_encoding ~safety :
(unsigned_create_payload, unsigned_create_payload_u, _) encoding =
conv
(fun (tx : unsigned_create_payload_u) -> (tx.pk, tx.fee))
(fun (pk, fee) -> {pk; fee})
(fun (tx : unsigned_create_payload) -> (tx.pk, tx.fee))
(fun (pk, fee) -> {pk; fee})
(obj2_encoding Schnorr.pk_encoding (fee_encoding ~safety))
let create_payload_encoding ~safety :
(create_payload, create_payload_u, _) encoding =
conv
(fun ({msg; signature} : create_payload_u) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(fun ({msg; signature} : create_payload) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(obj2_encoding
(unsigned_create_payload_encoding ~safety)
Schnorr.signature_encoding)
let create_encoding ~safety : (create, create_u, _) encoding =
conv
(fun (tx : create_u) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(fun (tx : create) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(obj2_encoding
(header_encoding ~safety)
(create_payload_encoding ~safety))
let create_storage_encoding : (create_storage, create_storage_u, _) encoding =
conv
(fun (tx : create_storage_u) -> (tx.dst, (tx.next_empty, tx.valid)))
(fun (dst, (next_empty, valid)) -> {dst; next_empty; valid})
(fun (tx : create_storage) -> (tx.dst, (tx.next_empty, tx.valid)))
(fun (dst, (next_empty, valid)) -> {dst; next_empty; valid})
(obj3_encoding tree_el_encoding tree_el_encoding bool_encoding)
let credit_payload_encoding ~safety :
(credit_payload, credit_payload_u, _) encoding =
conv
(fun (tx : credit_payload_u) -> (tx.cnt, (tx.dst, tx.amount)))
(fun (cnt, (dst, amount)) -> {cnt; dst; amount})
(fun (tx : credit_payload) -> (tx.cnt, (tx.dst, tx.amount)))
(fun (cnt, (dst, amount)) -> {cnt; dst; amount})
(obj3_encoding
(cnt_encoding ~safety)
(pos_encoding ~safety)
(ticket_amount_encoding ~safety))
let credit_encoding ~safety : (credit, credit_u, _) encoding =
conv
(fun (tx : credit_u) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(fun (tx : credit) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(obj2_encoding
(header_encoding ~safety)
(credit_payload_encoding ~safety))
let credit_storage_encoding : (credit_storage, credit_storage_u, _) encoding =
conv
(fun (tx : credit_storage_u) -> (tx.dst, tx.valid))
(fun (dst, valid) -> {dst; valid})
(fun (tx : credit_storage) -> (tx.dst, tx.valid))
(fun (dst, valid) -> {dst; valid})
(obj2_encoding tree_el_encoding bool_encoding)
let unsigned_debit_payload_encoding ~safety :
(unsigned_debit_payload, unsigned_debit_payload_u, _) encoding =
conv
(fun (tx : unsigned_debit_payload_u) -> (tx.cnt, (tx.src, tx.amount)))
(fun (cnt, (src, amount)) -> {cnt; src; amount})
(fun (tx : unsigned_debit_payload) -> (tx.cnt, (tx.src, tx.amount)))
(fun (cnt, (src, amount)) -> {cnt; src; amount})
(obj3_encoding
(cnt_encoding ~safety)
(pos_encoding ~safety)
(ticket_amount_encoding ~safety))
let debit_payload_encoding ~safety :
(debit_payload, debit_payload_u, _) encoding =
conv
(fun ({msg; signature} : debit_payload_u) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(fun ({msg; signature} : debit_payload) -> (msg, signature))
(fun (msg, signature) -> {msg; signature})
(obj2_encoding
(unsigned_debit_payload_encoding ~safety)
Schnorr.signature_encoding)
let debit_encoding ~safety : (debit, debit_u, _) encoding =
conv
(fun (tx : debit_u) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(fun (tx : debit) -> (tx.header, tx.payload))
(fun (header, payload) -> {header; payload})
(obj2_encoding (header_encoding ~safety) (debit_payload_encoding ~safety))
let debit_storage_encoding : (debit_storage, debit_storage_u, _) encoding =
conv
(fun (tx : debit_storage_u) -> (tx.src, tx.valid))
(fun (src, valid) -> {src; valid})
(fun (tx : debit_storage) -> (tx.src, tx.valid))
(fun (src, valid) -> {src; valid})
(obj2_encoding tree_el_encoding bool_encoding)
end