package octez-libs
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=ddfb5076eeb0b32ac21c1eed44e8fc86a6743ef18ab23fff02d36e365bb73d61
sha512=d22a827df5146e0aa274df48bc2150b098177ff7e5eab52c6109e867eb0a1f0ec63e6bfbb0e3645a6c2112de3877c91a17df32ccbff301891ce4ba630c997a65
doc/octez-libs.crypto-dal/Tezos_crypto_dal/Cryptobox/index.html
Module Tezos_crypto_dal.CryptoboxSource
Cryptography for the Data Availability Layer
The Data Availability Layer (DAL) reduces the storage strain on the blockchain by only storing on-chain constant-size cryptographic commitments to arbitrary data blobs called slots. The slots themselves are stored off-chain and are made available by the DAL.
A slot is encoded with some redundancy using a so-called MDS (Maximum Distance Separable) code. The resulting encoded slot is partitioned into shards, allowing retrieval of the slot with any subset of {!field:parameters.number_of_shards}/{!field:parameters.redundancy_factor} out of {!field:parameters.number_of_shards} shards. By doing so, we can guarantee high data availability provided a certain fraction of the DAL nodes is storing and supplying the data. This fraction can be made as small as desired at the expense of a higher data redundancy parameters.redundancy_factor. MDS codes have no unnecessary redundancy.
One can verify in constant time that the correct shard was retrieved using a constant-sized KZG proof shard_proof (see function verifyEval in section 3.3) and the slot commitment.
A slot is partioned into {!field:parameters.slot_size}/{!field:parameters.page_size} segments called Verifier.pages of size parameters.page_size. One can also verify in constant time that the correct page was retrieved using a KZG proof page_proof and the slot commitment.
A challenge is to keep the proving time for the shard_proofs almost proportional to the length n of the slot encoded with the MDS code: we've chosen and implemented a technique to produce the proofs in time O(n log n) (see Fast amortized KZG proofs).
Initial values for the parameters of the DAL cryptographic primitives. It used to build a value of type t.
Encapsulates parameters required to use the cryptographic primitives exported by this module. A value of type t contains both initial parameters and computed values depending on it.
Because of the shell/protocol separation, cryptographic primitives need to be splitted. An interface, called the Verifier aims to be provided for the economic protocol. The other interface, called the Builder is for the shell.
A Verifier, as hinted by the name, mainly needs to check proofs:
1. A proof that a commitment is valid
2. A proof that a page is valid
A technicality is that the economic protocol is able to configure those cryptographic primitives via several constants. Also, an SRS (aka trusted setup) is required.
It is the responsibility of the shell and the protocol to ensure that both the Verifier and the Builder are instantiated with the same parameters and use the same trusted setup.
Failed_to_load_trusted_setup, thrown by Config.init_dal.
type Tezos_error_monad.Error_monad.error += | Invalid_precomputation_hash of (string, string) error_container
Invalid_precomputation_hash, thrown by load_precompute_shards_proofs.
module Verifier :
Cryptobox_intf.VERIFIER
with type t = t
and type commitment = commitment
and type commitment_proof = commitment_proof
and type page_proof = page_proof
and type ('a, 'b) error_container = ('a, 'b) error_containerinclude Cryptobox_intf.VERIFIER
with type t := t
and type parameters :=
Tezos_crypto_dal_octez_dal_config.Dal_config.parameters
and type commitment := commitment
and type commitment_proof := commitment_proof
and type page_proof := page_proof
and type ('a, 'b) error_container := ('a, 'b) error_container
val parameters_encoding :
Tezos_crypto_dal_octez_dal_config.Dal_config.parameters Data_encoding.tAn encoding for values of type parameters.
val make :
Tezos_crypto_dal_octez_dal_config.Dal_config.parameters ->
(t, [> `Fail of string ]) resultmake precomputes the set of values needed by the cryptographic primitives defined in this module and stores them in a value of type t
parameters t returns the parameters given when t was initialised with the function make
verify_commitment t commitment proof returns true if and only if the size of the data committed via commitment does not exceed the slot_size declared in t.
The verification time is constant.
The original slot can be split into a list of pages of fixed size. This size is given by the parameter page_size given to the function make.
An encoding for the proof of a page.
pages_per_slot t returns the number of expected pages per slot.
val verify_page :
t ->
commitment ->
page_index:int ->
page ->
page_proof ->
(unit,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Invalid_page
| `Page_length_mismatch
| `Page_index_out_of_range ])
Result.tverify_page t commitment ~page_index page proof returns Ok () if the proof certifies that the page is the page_index-th page of the slot with the given commitment.
Fails with:
Error `Invalid_pageif the verification FailsError `Invalid_degree_strictly_less_than_expected _if the SRS contained intis too small to proceed with the verificationError `Page_length_mismatchif the page is not of the expected lengthpage_sizegiven for the initialisation oftError `Page_index_out_of_rangeifpage_indexis out of the range0, slot_size/page_size - 1whereslot_sizeandpage_sizeare given for the initialisation oft
Ensures:
verify_page t commitment ~page_index page proof = Ok ()if and only ifpage = Bytes.sub slot (page_index * t.page_size) t.page_size),proof = prove_page t polynomial page_index,p = polynomial_from_slot t slot, andcommitment = commit t p.
The primitives exposed in this modules require some preprocessing. This preprocessing generates data from an unknown secret. For the security of those primitives, it is important that the secret is unknown.
A slot is a byte sequence corresponding to some data.
The finited field used by the polynomial.
A polynomial is another representation for a slot. One advantage of this representation is that a commitment can be computed from a polynomial. A commitment has nice properties:
1. A commitment ensures that the size of the slot has a bounded size (typically slot_size).
2. A commitment can be used to verify that a page of fixed size (typically page_size) is part of the original slot.
polynomial_degree polynomial returns the degree of the polynomial.
polynomial_evaluate polynomial x evaluates polynomial(x).
val polynomial_from_slot :
t ->
slot ->
(polynomial, [> `Slot_wrong_size of string ]) Result.tpolynomial_from_slot t slot returns a polynomial from the a slot slot.
Requires:
Bytes.length slotis the slot size declared int.
Ensures:
- For any
slotsatisfyingBytes.length slotis equal to the declared slot size oft,polynomial_to_slot (polynomial_from_slot slot) = slot.
Fails with `Slot_wrong_size when the slot size is not equal to the value slot size declared in t.
Note:
polynomial_from_slotis injective.
polynomial_to_slot t polynomial returns a slot from a polynomial.
Ensures:
- For any
slotsatisfyingBytes.length slot = parameters.slot_size,polynomial_to_slot (polynomial_from_slot slot) = slot.
val commit :
t ->
polynomial ->
(commitment,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Prover_SRS_not_loaded ])
Result.tcommit t polynomial returns the commitment associated to a polynomial p.
Fails with `Invalid_degree_strictly_less_than_expected _ if the degree of p exceeds the SRS size.
Fails with `Prover_SRS_not_loaded if the prover’s SRS is not loaded (ie: init_dal_verifier has been used to load the SRS).
val pp_commit_error :
Format.formatter ->
[< `Invalid_degree_strictly_less_than_expected of (int, int) error_container
| `Prover_SRS_not_loaded ] ->
unitpp_commit_error fmt error pretty-prints the error returned by commit.
val string_of_commit_error :
[< `Invalid_degree_strictly_less_than_expected of (int, int) error_container
| `Prover_SRS_not_loaded ] ->
stringstring_of_commit_error error returns an error string message for error.
A portion of the data represented by a polynomial.
Encoding of a share.
A shard is share with its index (see shards_from_polynomial).
An encoding of a share.
encoded_share_size t returns the size of a share in byte depending on t
val polynomial_from_shards :
t ->
shard Seq.t ->
(polynomial,
[> `Not_enough_shards of string
| `Shard_index_out_of_range of string
| `Invalid_shard_length of string ])
resultpolynomial_from_shards t shards computes the original polynomial from shards. The proportion of shards needed is 1 over redundancy_factor the total number of shards declared in t.
Requires:
Seq.length shards >= number_of_shards / redundancy_factor(wherenumber_of_shardsandredundancy_factorare found int) .
Ensures:
- For any
p, letshards = shards_from_polynomial p, for any subset S of shards ofpolynomial_length / shard_lengthelements,polynomial_from_shards S = p. Here,polynomial_lengthandshard_lengthare parameters declared int.
Fails with:
Error (`Not_enough_shards msg)if there aren't at leastnumber_of_shards / redundancy_factorshards (where these two parameters are found int)Error (`Shard_index_out_of_range msg)if one shard index is not within the range0, number_of_shards - 1(wherenumber_of_shardsis declared int).Error (`Invalid_shard_length msg)if one shard is not of the expected length.
shards_from_polynomial t polynomial computes all the shards encoding the original polynomial.
Ensures:
- For any
p, letshards = shards_from_polynomial p, for any subset S of shards ofpolynomial_length / shard_lengthelements,polynomial_from_shards S = p. Here,polynomial_lengthandshard_lengthare parameters declared int. The shards in the returned sequence have increasing indexes.
A proof that a shard belongs to some commitment.
An encoding of a shard proof.
val verify_shard :
t ->
commitment ->
shard ->
shard_proof ->
(unit,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Invalid_shard
| `Shard_length_mismatch
| `Shard_index_out_of_range of string ])
Result.tverify_shard t commitment shard proof returns Ok () if shard is an element of shards_from_polynomial p where commitment = commit t p for some polynomial p.
The verification time is constant.
Requires:
- The SRS (structured reference string) contained in
tshould be the same as the one used to produce thecommitmentandproof.
Fails with:
Error `Invalid_shardif the verification failsError `Invalid_degree_strictly_less_than_expected _if the SRS contained intis too small to proceed with the verificationError `Shard_length_mismatchif the shard is not of the expected lengthshard_lengthgiven for the initialisation oftError (`Shard_index_out_of_range msg)if the shard index is not within the range0, number_of_shards - 1(wherenumber_of_shardsis found int).
Ensures:
verify_shard t commitment shard proof = Ok ()if and only ifArray.mem shard (shards_from_polynomial t polynomial),precomputation = precompute_shards_proofs t,proof = (prove_shards t ~precomputation ~polynomial).(shard.index), andcommitment = commit t p.
val verify_shard_multi :
t ->
commitment ->
shard list ->
shard_proof list ->
(unit,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Invalid_shard
| `Shard_length_mismatch
| `Shard_index_out_of_range of string ])
Result.tBatched version of verify_shard, for better verifier performance. verify_shard_multi t commitment shard_list proof_list returns Ok () if for all i List.nth i shard is an element of shards_from_polynomial p where commitment = commit t p for some polynomial p, and the proofs are correctly generated.
The verification time smaller than calling List.lenght shard_list times the verify_shard function.
Requires:
- The SRS (structured reference string) contained in
tshould be the same as the one used to produce thecommitmentandproof.
Fails with:
Error `Invalid_shardif the verification failsError `Invalid_degree_strictly_less_than_expected _if the SRS contained intis too small to proceed with the verificationError `Shard_length_mismatchif one of the shard is not of the expected lengthshard_lengthgiven for the initialisation oftError (`Shard_index_out_of_range msg)if one of the shard index is not within the range0, number_of_shards - 1(wherenumber_of_shardsis found int).
Ensures:
verify_shard_multi t commitment shard_list proof_list = Ok ()if and only ifArray.mem (List.nth i shard_list) (shards_from_polynomial t polynomial),precomputation = precompute_shards_proofs t,List.nth i proof_list = (prove_shards t ~precomputation ~polynomial). (List. nth i (shard_list.index)), for all i andcommitment = commit t p.
val prove_commitment :
t ->
polynomial ->
(commitment_proof,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Prover_SRS_not_loaded ])
Result.tprove_commitment t polynomial produces a proof that the slot represented by polynomial has its size bounded by slot_size declared in t.
Fails with:
Error `Invalid_degree_strictly_less_than_expected _if the SRS contained intis too small to produce the proofError `Prover_SRS_not_loadedif the prover’s SRS is not loaded (ie:init_dal_verifierhas been used to load the SRS).
val prove_page :
t ->
polynomial ->
int ->
(page_proof,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container
| `Page_index_out_of_range
| `Prover_SRS_not_loaded ])
Result.tprove_page t polynomial n produces a proof for the n-th page of the slot such that polynomial = polynomial_from_slot t slot. This proof can be used to verify given a commitment to a slot that a byte sequence is indeed the n-th page of the slot (see Ensures section below).
Fails with:
Error `Invalid_degree_strictly_less_than_expected _if the SRS contained intis too small to produce the proofError (`Page_index_out_of_range msg)if the page index is not within the range0, slot_size/page_size - 1(whereslot_sizeandpage_sizeare found int).Error `Prover_SRS_not_loadedif the SRS has been loaded withinit_dal_verifier.
Ensures:
verify_page t commitment ~page_index page page_proof = Ok ()if and only ifpage = Bytes.sub slot (page_index * t.page_size) t.page_size),page_proof = prove_page t polynomial page_index,p = polynomial_from_slot t slot, andcommitment = commit t p.
The precomputation used to produce shard proofs.
val precompute_shards_proofs :
t ->
(shards_proofs_precomputation,
[> `Invalid_degree_strictly_less_than_expected of
(int, int) error_container ])
Result.tprecomputation_shard_proofs t returns the precomputation used to produce shard proofs.
val save_precompute_shards_proofs :
shards_proofs_precomputation ->
filename:string ->
unit Tezos_error_monad.Error_monad.tzresult Lwt.tsave_precompute_shards_proofs precomputation ~filename saves the given precomputation to disk with the given filename.
val load_precompute_shards_proofs :
hash:Tezos_crypto.Blake2B.t option ->
filename:string ->
unit ->
shards_proofs_precomputation Tezos_error_monad.Error_monad.tzresult Lwt.tload_precompute_shards_proofs ~hash ~filename () loads the precomputation from disk from the given filename. If hash is not None, an integrity check of the retrieved precomputation is performed.
Returns the error Invalid_precomputation_hash if the integrity check fails.
hash_precomputation precomputation returns the Tezos_crypto.Blake2B.t hash of the Data_encoding.t value of precomputation.
val prove_shards :
t ->
precomputation:shards_proofs_precomputation ->
polynomial:polynomial ->
shard_proof arrayprove_shards t ~precomputation ~polynomial produces number_of_shards proofs (π_0, ..., π_{number_of_shards - 1}) for the elements of polynomial_from_shards polynomial (where number_of_shards is declared in t) using the precomputation.
Requires:
polynomial = polynomial_from_slot t sfor some slotsand the same valuetused inprove_shards. Since the caller ofprove_shardsknowspolynomial, it is its responsibility to enforce this requirement.precomputation = precompute_shards_proofs twith the same valuetused inprove_shards. There is no way for this function to check that theprecomputationis correct since it doesn't compute it.
Ensures:
verify_shard t commitment shard proof = Ok ()if and only ifArray.mem shard (shards_from_polynomial t polynomial)proof = (prove_shards t polynomial).(shard.index), andcommitment = commit t polynomial.