diff --git a/src/lib_sapling/core.ml b/src/lib_sapling/core.ml index 406fbc096638d5c17d79fe26d3105810279fc25e..b84f61fd608003c2001f5b7c8463007f1e0794e8 100644 --- a/src/lib_sapling/core.ml +++ b/src/lib_sapling/core.ml @@ -138,7 +138,15 @@ module Raw = struct let diversifier_encoding = let open Data_encoding in def "sapling.wallet.diversifier" - @@ conv R.of_diversifier R.to_diversifier (Fixed.bytes 11) + @@ conv + R.of_diversifier + (fun b -> + match R.to_diversifier b with + | Some diversifier -> + diversifier + | None -> + raise (Invalid_argument "diversifier_encoding: decoding")) + (Fixed.bytes 11) (** Full viewing key contains ak, nsk, ovk *) type full_viewing_key = R.full_viewing_key = {ak : ak; nk : nk; ovk : ovk} @@ -284,21 +292,24 @@ module Raw = struct (* Creates an unspendable address since the ivk is generated at random *) let dummy_address () = + (* NOTE: the density of valid diversifiers is roughly half. This loop is + likely to be short. *) let rec random_diversifier () = - let res = R.to_diversifier @@ Hacl.Rand.gen 11 in - if R.check_diversifier res then res else random_diversifier () + match R.to_diversifier @@ Hacl.Rand.gen 11 with + | Some diversifier -> + diversifier + | None -> + random_diversifier () in let diversifier = random_diversifier () in (* A random ivk is 32 bytes with the first 5 bits set to 0 *) let rand = Hacl.Rand.gen 32 in - let mask = 7 (* 00000111 *) in + let mask = 0b00000111 in let int = Char.code @@ Bytes.get rand 0 in let int_masked = int land mask in Bytes.set rand 0 (Char.chr int_masked) ; let ivk = R.to_ivk rand in - let pkd = - R.ivk_to_pkd ivk diversifier |> TzOption.unopt_assert ~loc:__POS__ - in + let pkd = R.ivk_to_pkd ivk diversifier in {diversifier; pkd} end @@ -322,7 +333,6 @@ module Raw = struct (ie. epk is used for symkey_receiver). *) let derive_ephemeral address esk = R.ka_derivepublic Viewing_key.(address.diversifier) esk - |> TzOption.unopt_assert ~loc:__POS__ (* used to derive symmetric keys from the diffie hellman. *) let kdf_key = Bytes.of_string "KDFSaplingForTezosV1" @@ -330,20 +340,12 @@ module Raw = struct (** Derives a symmetric key to be used to create the ciphertext on the sender side. *) let symkey_sender esk pkd = - let symkey = - R.of_symkey - @@ TzOption.unopt_assert ~loc:__POS__ - @@ R.ka_agree_sender pkd esk - in + let symkey = R.of_symkey @@ R.ka_agree_sender pkd esk in let hash = Blake2B.(to_bytes @@ hash_bytes ~key:kdf_key [symkey]) in Crypto_box.Secretbox.unsafe_of_bytes hash let symkey_receiver epk ivk = - let symkey = - R.of_symkey - @@ TzOption.unopt_assert ~loc:__POS__ - @@ R.ka_agree_receiver epk ivk - in + let symkey = R.of_symkey @@ R.ka_agree_receiver epk ivk in let hash = Blake2B.(to_bytes @@ hash_bytes ~key:kdf_key [symkey]) in Crypto_box.Secretbox.unsafe_of_bytes hash @@ -409,9 +411,7 @@ module Raw = struct let compute address xfvk ~amount rcm ~position = let open Viewing_key in - let open TzOption in - R.ivk_to_pkd (to_ivk xfvk) address.diversifier - >>= fun pkd -> + let pkd = R.ivk_to_pkd (to_ivk xfvk) address.diversifier in R.compute_nf address.diversifier pkd @@ -569,18 +569,16 @@ module Raw = struct let decrypt ciphertext xfvk = let ivk = Viewing_key.to_ivk xfvk in let symkey = DH.symkey_receiver ciphertext.epk ivk in - let open TzOption in + let ( >?? ) = Stdlib.Option.bind in Crypto_box.Secretbox.secretbox_open symkey ciphertext.payload_enc ciphertext.nonce_enc - >>= fun plaintext -> + >?? fun plaintext -> let {diversifier; amount; rcm; memo} = Data_encoding.Binary.of_bytes_exn plaintext_encoding plaintext in - let pkd = - R.ivk_to_pkd ivk diversifier |> TzOption.unopt_assert ~loc:__POS__ - in + let pkd = R.ivk_to_pkd ivk diversifier in Some (Viewing_key.{pkd; diversifier}, amount, rcm, memo) (* Get ciphertext with only the outgoing viewing key, @@ -588,12 +586,12 @@ module Raw = struct let decrypt_ovk ciphertext ovk (cm, epk) = (* symkey for payload_out *) let symkey = DH.symkey_out ovk (ciphertext.cv, cm, epk) in - let open TzOption in + let ( >?? ) = Stdlib.Option.bind in Crypto_box.Secretbox.secretbox_open symkey ciphertext.payload_out ciphertext.nonce_out - >>= fun plaintext -> + >?? fun plaintext -> let (pkd, esk) = decompose_plaintext_out plaintext in (* symkey for payload_enc *) let symkey = DH.symkey_sender esk pkd in @@ -601,7 +599,7 @@ module Raw = struct symkey ciphertext.payload_enc ciphertext.nonce_enc - >>= fun plaintext -> + >?? fun plaintext -> let {diversifier; amount; rcm; memo} = Data_encoding.Binary.of_bytes_exn plaintext_encoding plaintext in @@ -814,7 +812,6 @@ module Raw = struct ~amount ~root ~witness - |> TzOption.unopt_assert ~loc:__POS__ let spend_sig xsp ar cv nf rk proof key_string = let sighash = UTXO.hash_input cv nf rk proof key_string in @@ -828,7 +825,6 @@ module Raw = struct address.pkd rcm ~amount - |> TzOption.unopt_assert ~loc:__POS__ let make_binding_sig ctx inputs outputs ~balance key = let sighash = UTXO.hash_transaction inputs outputs key in @@ -932,8 +928,7 @@ module Raw = struct let check_cm i existing_cm = Rcm.assert_valid i.rcm ; let computed_cm = - TzOption.unopt_assert ~loc:__POS__ - @@ Commitment.compute i.address ~amount:i.amount i.rcm + Commitment.compute i.address ~amount:i.amount i.rcm in if existing_cm = computed_cm then true else false end @@ -944,10 +939,7 @@ module Raw = struct (* Prepare the ciphertext and the commitment *) let to_ciphertext o cv vk rcm esk = - let cm = - Commitment.compute o.address ~amount:o.amount rcm - |> TzOption.unopt_assert ~loc:__POS__ - in + let cm = Commitment.compute o.address ~amount:o.amount rcm in let epk = DH.derive_ephemeral o.address esk in let to_be_hashed = (cv, cm, epk) in let ciphertext = @@ -957,10 +949,7 @@ module Raw = struct (* Prepare the ciphertext that won't decrypt under ovk and the commitment *) let to_ciphertext_without_ovk o rcm esk cv = - let cm = - Commitment.compute o.address ~amount:o.amount rcm - |> TzOption.unopt_assert ~loc:__POS__ - in + let cm = Commitment.compute o.address ~amount:o.amount rcm in let ciphertext = Ciphertext.encrypt_without_ovk o.amount o.address rcm o.memo esk cv in diff --git a/src/lib_sapling/core_sig.ml b/src/lib_sapling/core_sig.ml index 734da48233234055ea4815e22515c51584955462..58ea8100cbc9d057704ec1aa31a4eb9defa94e23 100644 --- a/src/lib_sapling/core_sig.ml +++ b/src/lib_sapling/core_sig.ml @@ -359,7 +359,7 @@ module type Commitment = sig include T_encoding_bytes - val compute : viewing_key_address -> amount:int64 -> rcm -> t option + val compute : viewing_key_address -> amount:int64 -> rcm -> t val valid_position : int64 -> bool end @@ -386,7 +386,7 @@ module type Nullifier = sig amount:int64 -> rcm -> position:int64 -> - t option + t end module type Rcm = sig @@ -449,7 +449,7 @@ module type Client = sig UTXO.rk -> UTXO.spend_proof -> string -> - UTXO.spend_sig option + UTXO.spend_sig val spend_proof : t -> @@ -478,7 +478,7 @@ module type Client = sig UTXO.output list -> balance:int64 -> string -> - UTXO.binding_sig option + UTXO.binding_sig end module Forge : sig diff --git a/src/lib_sapling/dune b/src/lib_sapling/dune index b51f0f97d20e288a516cb69a9d0a45c028bddfaf..0560a191f5d989c49aede146e6cb0e09a7b1e244 100644 --- a/src/lib_sapling/dune +++ b/src/lib_sapling/dune @@ -6,7 +6,7 @@ (library (name tezos_sapling) (public_name tezos-sapling) - (libraries ctypes ctypes.foreign ctypes.stubs hex data-encoding tezos-crypto tezos-stdlib tezos-error-monad) + (libraries ctypes ctypes.foreign ctypes.stubs hex data-encoding tezos-crypto tezos-stdlib tezos-error-monad tezos-lwt-result-stdlib) (foreign_stubs (language c) (flags (-I%{env:OPAM_SWITCH_PREFIX=}/lib/tezos-rust-libs)) @@ -14,7 +14,8 @@ (c_library_flags (-L%{env:OPAM_SWITCH_PREFIX=}/lib/tezos-rust-libs -lrustzcash -lpthread)) (flags (:standard -open Tezos_stdlib -open Tezos_crypto - -open Tezos_error_monad))) + -open Tezos_error_monad + -open Tezos_lwt_result_stdlib.Lwtreslib))) (rule (alias runtest_lint) diff --git a/src/lib_sapling/forge.ml b/src/lib_sapling/forge.ml index c69b1921bcffe80e18181f55e58a0c4c5f23a500..c35adf0ca6c6f9918be5cebd491cd4a53578c631 100644 --- a/src/lib_sapling/forge.ml +++ b/src/lib_sapling/forge.ml @@ -40,7 +40,6 @@ module Input = struct ~amount:forge_input.amount forge_input.rcm ~position:forge_input.pos - |> TzOption.unopt_assert ~loc:__POS__ in S.mem_nullifier state nf @@ -75,10 +74,7 @@ let dummy_input anti_replay ctx dummy_witness root = let sk = Core.Spending_key.of_seed seed in let vk = Core.Viewing_key.of_sk sk in let addr = Core.Viewing_key.dummy_address () in - let nf = - Core.Nullifier.compute addr vk ~amount:0L rcm ~position:0L - |> TzOption.unopt_assert ~loc:__POS__ - in + let nf = Core.Nullifier.compute addr vk ~amount:0L rcm ~position:0L in let ar = Core.Proving.ar_random () in (* The proof is considered valid even with a dummy witness if the amount given is 0. *) @@ -94,20 +90,21 @@ let dummy_input anti_replay ctx dummy_witness root = ~root ~witness:dummy_witness in - let signature = - Core.Proving.spend_sig sk ar cv nf rk proof_i anti_replay - |> TzOption.unopt_assert ~loc:__POS__ - in + let signature = Core.Proving.spend_sig sk ar cv nf rk proof_i anti_replay in Core.UTXO.{cv; nf; rk; proof_i; signature} let create_dummy_inputs n state anti_replay ctx = + (* assertion already checked by callers *) + assert (n >= 0) ; (* In order to get a valid witness we simply use the one of the first element *) let not_empty = S.mem state 0L in - if n > 0 && not_empty then + if not_empty then (* Doesn't make sense to create dummy_inputs with an empty storage *) let dummy_witness = S.get_witness state 0L in let root = S.get_root state in - List.init n (fun _ -> dummy_input anti_replay ctx dummy_witness root) + List.init ~when_negative_length:() n (fun _ -> + dummy_input anti_replay ctx dummy_witness root) + |> Result.get_ok else [] let dummy_output pctx ~memo_size = @@ -125,6 +122,16 @@ let dummy_output pctx ~memo_size = let forge_transaction ?(number_dummy_inputs = 0) ?(number_dummy_outputs = 0) (forge_inputs : Input.t list) (forge_outputs : output list) (sp : Core.Spending_key.t) (anti_replay : string) (state : S.state) = + if number_dummy_inputs < 0 then + raise + (Invalid_argument + "Tezos_sapling.Forge.forge_transaction: number_dummy_inputs is \ + negative") ; + if number_dummy_outputs < 0 then + raise + (Invalid_argument + "Tezos_sapling.Forge.forge_transaction: number_dummy_outputs is \ + negative") ; let memo_size = S.get_memo_size state in List.iter (fun forge_output -> @@ -159,11 +166,9 @@ let forge_transaction ?(number_dummy_inputs = 0) ?(number_dummy_outputs = 0) ~amount:i.amount i.rcm ~position:i.pos - |> TzOption.unopt_assert ~loc:__POS__ in let signature = Core.Proving.spend_sig sp ar cv nf rk proof_i anti_replay - |> TzOption.unopt_assert ~loc:__POS__ in Core.UTXO.{cv; nf; rk; proof_i; signature}) forge_inputs @@ -211,17 +216,14 @@ let forge_transaction ?(number_dummy_inputs = 0) ?(number_dummy_outputs = 0) in let inputs = real_inputs @ dummy_inputs in let dummy_outputs = - List.init number_dummy_outputs (fun _ -> dummy_output ctx ~memo_size) + List.init ~when_negative_length:() number_dummy_outputs (fun _ -> + dummy_output ctx ~memo_size) + |> Result.get_ok + (* checked at entrance of function *) in let outputs = real_outputs @ dummy_outputs in let binding_sig = - TzOption.unopt_assert ~loc:__POS__ - @@ Core.Proving.make_binding_sig - ctx - inputs - outputs - ~balance - anti_replay + Core.Proving.make_binding_sig ctx inputs outputs ~balance anti_replay in Core.UTXO.{inputs; outputs; binding_sig; balance; root}) @@ -232,6 +234,16 @@ let forge_transaction ?(number_dummy_inputs = 0) ?(number_dummy_outputs = 0) let forge_shield_transaction ?(number_dummy_inputs = 0) ?(number_dummy_outputs = 0) (forge_outputs : output list) (balance : int64) (anti_replay : string) (state : S.state) = + if number_dummy_inputs < 0 then + raise + (Invalid_argument + "Tezos_sapling.Forge.forge_shield_transaction: number_dummy_inputs \ + is negative") ; + if number_dummy_outputs < 0 then + raise + (Invalid_argument + "Tezos_sapling.Forge.forge_shield_transaction: number_dummy_outputs \ + is negative") ; let memo_size = S.get_memo_size state in List.iter (fun forge_output -> @@ -276,16 +288,18 @@ let forge_shield_transaction ?(number_dummy_inputs = 0) create_dummy_inputs number_dummy_inputs state anti_replay ctx in let dummy_outputs = - List.init number_dummy_outputs (fun _ -> dummy_output ctx ~memo_size) + List.init ~when_negative_length:() number_dummy_outputs (fun _ -> + dummy_output ctx ~memo_size) + |> Result.get_ok + (* checked at entrance of function *) in let outputs = real_outputs @ dummy_outputs in let binding_sig = - TzOption.unopt_assert ~loc:__POS__ - @@ Core.Proving.make_binding_sig - ctx - [] - outputs - ~balance:balance_outputs - anti_replay + Core.Proving.make_binding_sig + ctx + [] + outputs + ~balance:balance_outputs + anti_replay in Core.UTXO.{inputs = dummy_inputs; outputs; binding_sig; balance; root}) diff --git a/src/lib_sapling/forge.mli b/src/lib_sapling/forge.mli index ceaeedf04dbd017759412e7a8d2d3ae01f92db19..b3a009b33e48b757408140a69913350e7adf71a6 100644 --- a/src/lib_sapling/forge.mli +++ b/src/lib_sapling/forge.mli @@ -50,6 +50,8 @@ type output val make_output : Core.Viewing_key.address -> int64 -> Bytes.t -> output +(* @raise [Invalid_argument] if eitner of [number_dummy_inputs] or + [number_dummy_outputs] is strictly negative *) val forge_transaction : ?number_dummy_inputs:int -> ?number_dummy_outputs:int -> @@ -60,6 +62,8 @@ val forge_transaction : S.state -> Core.UTXO.transaction +(* @raise [Invalid_argument] if eitner of [number_dummy_inputs] or + [number_dummy_outputs] is strictly negative *) val forge_shield_transaction : ?number_dummy_inputs:int -> ?number_dummy_outputs:int -> diff --git a/src/lib_sapling/rustzcash.ml b/src/lib_sapling/rustzcash.ml index 6c75ea6c0fd5937b0fb72c171bed8973461f14ac..9e1e45019778b6693055d64a8ce757c6de08f87f 100644 --- a/src/lib_sapling/rustzcash.ml +++ b/src/lib_sapling/rustzcash.ml @@ -25,7 +25,15 @@ any function. Amounts are bounded by [-max_amount, +max_amount] so it fits in a int64. The positions we use are bounded by [ 0 ; 4294967295], which is an uint32, but - for simplicity they are stored in a int64. *) + for simplicity they are stored in a int64. + Functions in librustzcash return [false] when their arguments are malformed, + and return [true] otherwise (in which case result buffer contains the + result). Because we lean on the OCaml type system to enforce that arguments + are well-formed, we simply [assert] on the return value of the rust bindings. + *) + +(* Ctypes binding. We encapsulate the binding in a specific module *) +module RS = Rustzcash_ctypes_bindings.Bindings (Rustzcash_ctypes_stubs) module T : Rustzcash_sig.T = struct type ask = Bytes.t @@ -188,9 +196,12 @@ module T : Rustzcash_sig.T = struct assert (Bytes.length x = 64) ; x + let check_diversifier_bytes diversifier = + RS.check_diversifier (Ctypes.ocaml_bytes_start diversifier) + let to_diversifier x = assert (Bytes.length x = 11) ; - x + if check_diversifier_bytes x then Some x else None let to_diversifier_index x = assert (Bytes.length x = 11) ; @@ -365,9 +376,6 @@ let valid_position pos = let max_uint32 = 4294967295L in Compare.Int64.(pos >= 0L && pos <= max_uint32) -(* Ctypes binding. We encapsulate the binding in a specific module *) -module RS = Rustzcash_ctypes_bindings.Bindings (Rustzcash_ctypes_stubs) - (* We don't load sprout's parameters. Parameters of type Rust `usize` are converted to OCaml `int` because they are only file paths. NULL is a void pointer. @@ -425,7 +433,8 @@ let ivk_to_pkd ivk diversifier = (Ctypes.ocaml_bytes_start (of_diversifier diversifier)) (Ctypes.ocaml_bytes_start pkd) in - if res then Some (to_pkd pkd) else None + assert res ; + to_pkd pkd let generate_r () = let res = Bytes.create 32 in @@ -448,7 +457,8 @@ let compute_nf diversifier pk_d ~amount r ak nk ~position = (Unsigned.UInt64.of_int64 position) (Ctypes.ocaml_bytes_start nf) in - if res then Some (to_nullifier nf) else None + assert res ; + to_nullifier nf let compute_cm diversifier pk_d ~amount rcm = if not (valid_amount amount) then invalid_arg "amount" @@ -462,7 +472,8 @@ let compute_cm diversifier pk_d ~amount rcm = (Ctypes.ocaml_bytes_start (of_rcm rcm)) (Ctypes.ocaml_bytes_start cm) in - if res then Some (to_commitment cm) else None + assert res ; + to_commitment cm let ka_agree (p : Bytes.t) (sk : Bytes.t) = let ka = Bytes.create 32 in @@ -472,7 +483,8 @@ let ka_agree (p : Bytes.t) (sk : Bytes.t) = (Ctypes.ocaml_bytes_start sk) (Ctypes.ocaml_bytes_start ka) in - if res then Some (to_symkey ka) else None + assert res ; + to_symkey ka let ka_agree_sender (p : pkd) (sk : esk) = ka_agree (of_pkd p) (of_esk sk) @@ -486,7 +498,8 @@ let ka_derivepublic diversifier esk = (Ctypes.ocaml_bytes_start (of_esk esk)) (Ctypes.ocaml_bytes_start epk) in - if res then Some (to_epk epk) else None + assert res ; + to_epk epk let spend_sig ask ar sighash = let signature = Bytes.create 64 in @@ -497,7 +510,8 @@ let spend_sig ask ar sighash = (Ctypes.ocaml_bytes_start (of_sighash sighash)) (Ctypes.ocaml_bytes_start signature) in - if res then Some (to_spend_sig signature) else None + assert res ; + to_spend_sig signature type proving_ctx = unit Ctypes_static.ptr @@ -548,7 +562,8 @@ let spend_proof ctx ak nsk diversifier rcm ar ~amount ~root ~witness = (Ctypes.ocaml_bytes_start rk) (Ctypes.ocaml_bytes_start zkproof) in - if res then Some (to_cv cv, to_rk rk, to_spend_proof zkproof) else None + assert res ; + (to_cv cv, to_rk rk, to_spend_proof zkproof) let check_spend verification_ctx cv root nullifier rk spend_proof spend_sig sighash = @@ -573,7 +588,8 @@ let make_binding_sig ctx ~balance sighash = (Ctypes.ocaml_bytes_start (of_sighash sighash)) (Ctypes.ocaml_bytes_start binding_sig) in - if res then Some (to_binding_sig binding_sig) else None + assert res ; + to_binding_sig binding_sig let output_proof ctx esk diversifier pk_d rcm ~amount = if not (valid_amount amount) then invalid_arg "amount" @@ -593,7 +609,8 @@ let output_proof ctx esk diversifier pk_d rcm ~amount = (Ctypes.ocaml_bytes_start cv) (Ctypes.ocaml_bytes_start zkproof) in - if res then Some (to_cv cv, to_output_proof zkproof) else None + assert res ; + (to_cv cv, to_output_proof zkproof) let check_output verification_ctx cv commitment epk output_proof = RS.sapling_check_output @@ -638,7 +655,11 @@ let zip32_xfvk_address xfvk j = let pkd = Bytes.create 32 in Bytes.blit addr 0 diversifier 0 11 ; Bytes.blit addr 11 pkd 0 32 ; - Some (to_diversifier_index j_ret, to_diversifier diversifier, to_pkd pkd) ) + let diversifier = + (* This value is returned from the lib, it is a valid diversifier *) + Option.get @@ to_diversifier diversifier + in + Some (to_diversifier_index j_ret, diversifier, to_pkd pkd) ) else None let to_scalar input = @@ -669,7 +690,8 @@ let zip32_xfvk_derive parent index = (Unsigned.UInt32.of_int32 index) (Ctypes.ocaml_bytes_start derived) in - if res then Some (to_zip32_full_viewing_key derived) else None + assert res ; + to_zip32_full_viewing_key derived exception Params_not_found of string list diff --git a/src/lib_sapling/rustzcash.mli b/src/lib_sapling/rustzcash.mli index c998674088bccd07750e6e5f0822af2f3a732587..6dda3098220265f9b6d9d8ee7ed5656f5068407e 100644 --- a/src/lib_sapling/rustzcash.mli +++ b/src/lib_sapling/rustzcash.mli @@ -63,8 +63,13 @@ val crh_ivk : ak -> nk -> ivk (** Checks that a potential diversifier respects the needed properties *) val check_diversifier : diversifier -> bool -(** Computes a diversified pk that the payee gives to the payer offline *) -val ivk_to_pkd : ivk -> diversifier -> pkd option +(** Computes a diversified pk that the payee gives to the payer offline. + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val ivk_to_pkd : ivk -> diversifier -> pkd (** Gives a random scalar *) val generate_r : unit -> Bytes.t @@ -72,7 +77,12 @@ val generate_r : unit -> Bytes.t (** Computes a nullifier. The first int64 is the amount of the note, the second is the position you want it inserted in. The rcm should be the same as the one to compute cm and the spend or output - proof, and should be generated using generate_r. *) + proof, and should be generated using generate_r. + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) val compute_nf : diversifier -> pkd -> @@ -81,32 +91,52 @@ val compute_nf : ak -> nk -> position:int64 -> - nullifier option + nullifier (** Computes a commitment. The int64 is the amount, and the rcm is the same than for the nullifier and output or spend proof. It should be generated at - random using generate_r. *) -val compute_cm : diversifier -> pkd -> amount:int64 -> rcm -> commitment option + random using generate_r. + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val compute_cm : diversifier -> pkd -> amount:int64 -> rcm -> commitment (** Computes the shared secret of a Diffie Hellman key exchange (on the JubJub curve) with base depending on the diversifier. For the sender the epk is the pkd of the receiver, the esk was generated by him using generate_r. For the receiver the epk is the one published by the sender, and the secret is - his ivk. *) -val ka_agree_sender : pkd -> esk -> symkey option + his ivk. -val ka_agree_receiver : epk -> ivk -> symkey option + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val ka_agree_sender : pkd -> esk -> symkey + +val ka_agree_receiver : epk -> ivk -> symkey (** Computes the ephemeral pk from the ephemeral sk for a Diffie Hellman key exchange. This is used by the sender. The esk should be generated using - generate_r *) -val ka_derivepublic : diversifier -> esk -> epk option + generate_r + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val ka_derivepublic : diversifier -> esk -> epk (** Creates the spend sig for an input. The sighash argument is the hash of the input ie. cv,cm,... - The has to be generated using generate_r *) -val spend_sig : ask -> ar -> sighash -> spend_sig option + The has to be generated using generate_r + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val spend_sig : ask -> ar -> sighash -> spend_sig type proving_ctx @@ -128,11 +158,20 @@ val with_proving_ctx : (proving_ctx -> 'a) -> 'a outputs is the same as the given balance. The necessary information is stored in the proving context when creating the proofs for inputs and outputs. The proving context has to be freed after - calling this function. *) -val make_binding_sig : - proving_ctx -> balance:int64 -> sighash -> binding_sig option + calling this function. + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) +val make_binding_sig : proving_ctx -> balance:int64 -> sighash -> binding_sig -(** Creates proof and sig for an output *) +(** Creates proof and sig for an output + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) val output_proof : proving_ctx -> esk -> @@ -140,12 +179,17 @@ val output_proof : pkd -> rcm -> amount:int64 -> - (cv * output_proof) option + cv * output_proof (** Creates the zk proof and sig for an input. The first is the same as the one for the commitment and nullifier. The second one is the same as for the binding sig. - This function can panic (e.g. if the arguments are not coherent). *) + This function can panic (e.g. if the arguments are not coherent). + + @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) val spend_proof : proving_ctx -> ak -> @@ -156,7 +200,7 @@ val spend_proof : amount:int64 -> root:hash -> witness:Bytes.t -> - (cv * rk * spend_proof) option + cv * rk * spend_proof (** Reduces mod r_j, takes a 64 bytes input*) val to_scalar : Bytes.t -> Bytes.t @@ -206,5 +250,9 @@ val zip32_xfvk_address : val zip32_xsk_derive : zip32_expanded_spending_key -> Int32.t -> zip32_expanded_spending_key +(* @raise [Assert_failure] if the underlying binding in rust indicates a failure, + which only happens if the arguments are not valid representations for their + expected type, which can only happen if there's an error in the constructors + for these abstract types. *) val zip32_xfvk_derive : - zip32_full_viewing_key -> Int32.t -> zip32_full_viewing_key option + zip32_full_viewing_key -> Int32.t -> zip32_full_viewing_key diff --git a/src/lib_sapling/rustzcash_sig.ml b/src/lib_sapling/rustzcash_sig.ml index 49766aea1be4767c4a016184a81e437cad9bb7e6..59a5e421dbfd610f26da3ae16efd3b8986232821 100644 --- a/src/lib_sapling/rustzcash_sig.ml +++ b/src/lib_sapling/rustzcash_sig.ml @@ -146,7 +146,7 @@ module type T = sig val to_binding_sig : Bytes.t -> binding_sig - val to_diversifier : Bytes.t -> diversifier + val to_diversifier : Bytes.t -> diversifier option val to_diversifier_index : Bytes.t -> diversifier_index diff --git a/src/lib_sapling/storage.ml b/src/lib_sapling/storage.ml index 47e63afd0bcbed98b3df1075b3ef329bfe9085ad..d207ad61a58425f6ec2d8620ba55582d46f20d19 100644 --- a/src/lib_sapling/storage.ml +++ b/src/lib_sapling/storage.ml @@ -356,7 +356,7 @@ module Make_Storage (C : Core_sig.Validator) = struct let size = Map.cardinal - let find_opt = Map.find_opt + let find_opt = Map.find let mem = Map.mem @@ -382,7 +382,7 @@ module Make_Storage (C : Core_sig.Validator) = struct let get_from t pos = let rec aux pos acc = - match Map.find_opt pos t with + match Map.find pos t with | None -> acc | Some e -> diff --git a/src/lib_sapling/test/keys.ml b/src/lib_sapling/test/keys.ml index 82f43b9784093fe6b88d0eda53d95cf18007e31d..c5b9427bf0625c5445dcaa1dbdf126776e81cccb 100644 --- a/src/lib_sapling/test/keys.ml +++ b/src/lib_sapling/test/keys.ml @@ -45,7 +45,7 @@ module Vector = struct ak = R.to_ak @@ ba_of_hex ak; nk = R.to_nk @@ ba_of_hex nk; ivk = R.to_ivk @@ ba_of_hex ivk; - default_d = R.to_diversifier @@ ba_of_hex default_d; + default_d = Option.get @@ R.to_diversifier @@ ba_of_hex default_d; default_pk_d = R.to_pkd @@ ba_of_hex default_pk_d; note_v; note_r = R.to_rcm @@ ba_of_hex note_r; @@ -110,23 +110,24 @@ let vectors_zip32 = let open R in let vector_of_strings ask nsk ovk dk c ak nk ivk xsk xfvk fp d0 d1 d2 dmax = let opt s = if s = "None" then None else Some (ba_of_hex s) in - let open TzOption in + let ( >?| ) x f = Stdlib.Option.map f x in + let ( >?? ) = Stdlib.Option.bind in { - ask = opt ask >>| to_ask; - nsk = opt nsk >>| to_nsk; + ask = opt ask >?| to_ask; + nsk = opt nsk >?| to_nsk; ovk = to_ovk @@ ba_of_hex ovk; dk = ba_of_hex dk; c = ba_of_hex c; ak = to_ak @@ ba_of_hex ak; nk = to_nk @@ ba_of_hex nk; ivk = to_ivk @@ ba_of_hex ivk; - xsk = opt xsk >>= Sk.of_bytes; - xfvk = unopt_assert ~loc:__POS__ @@ Vk.of_bytes @@ ba_of_hex xfvk; + xsk = opt xsk >?? Sk.of_bytes; + xfvk = Stdlib.Option.get @@ Vk.of_bytes @@ ba_of_hex xfvk; fp = ba_of_hex fp; - d0 = opt d0 >>| to_diversifier; - d1 = opt d1 >>| to_diversifier; - d2 = opt d2 >>| to_diversifier; - dmax = opt dmax >>| to_diversifier; + d0 = opt d0 >?? to_diversifier; + d1 = opt d1 >?? to_diversifier; + d2 = opt d2 >?? to_diversifier; + dmax = opt dmax >?? to_diversifier; } in (* read file in memory skipping lines with # *) @@ -170,7 +171,7 @@ let xsks_raw = acc | Some xsk -> xsk |> R.of_zip32_expanded_spending_key |> Sk.of_bytes - |> TzOption.unopt_assert ~loc:__POS__ + |> Stdlib.Option.get |> fun xsk -> xsk :: acc) [] vectors_zip32 @@ -179,6 +180,5 @@ let xsks = List.map (fun x -> R.of_zip32_expanded_spending_key x - |> Core.Wallet.Spending_key.of_bytes - |> TzOption.unopt_assert ~loc:__POS__) + |> Core.Wallet.Spending_key.of_bytes |> Stdlib.Option.get) xsks_raw diff --git a/src/lib_sapling/test/test_keys.ml b/src/lib_sapling/test/test_keys.ml index 4065a32d98488d0be7f89bf0af3a4024aff5801f..6b5e88fe9b1fa2fb3a8e56b745519a1b27f3d3be 100644 --- a/src/lib_sapling/test/test_keys.ml +++ b/src/lib_sapling/test/test_keys.ml @@ -12,40 +12,26 @@ let test_keys () = assert (nk = v.nk) ; let ivk = R.crh_ivk ak nk in assert (ivk = v.ivk) ; - let pkd = - TzOption.unopt_assert ~loc:__POS__ (R.ivk_to_pkd ivk v.default_d) - in + let pkd = R.ivk_to_pkd ivk v.default_d in assert (pkd = v.default_pk_d) ; assert (R.check_diversifier v.default_d) ; let nf = - TzOption.unopt_assert - ~loc:__POS__ - (R.compute_nf - v.default_d - pkd - ~amount:v.note_v - v.note_r - ak - nk - ~position:v.note_pos) + R.compute_nf + v.default_d + pkd + ~amount:v.note_v + v.note_r + ak + nk + ~position:v.note_pos in assert (nf = v.note_nf) ; - let cm = - TzOption.unopt_assert - ~loc:__POS__ - (R.compute_cm v.default_d pkd ~amount:v.note_v v.note_r) - in + let cm = R.compute_cm v.default_d pkd ~amount:v.note_v v.note_r in assert (cm = v.note_cm) ; let esk = R.to_esk @@ R.generate_r () in - let epk = - TzOption.unopt_assert ~loc:__POS__ (R.ka_derivepublic v.default_d esk) - in - let ka1 = - TzOption.unopt_assert ~loc:__POS__ (R.ka_agree_sender pkd esk) - in - let ka2 = - TzOption.unopt_assert ~loc:__POS__ (R.ka_agree_receiver epk ivk) - in + let epk = R.ka_derivepublic v.default_d esk in + let ka1 = R.ka_agree_sender pkd esk in + let ka2 = R.ka_agree_receiver epk ivk in assert (ka1 = ka2)) vectors @@ -106,14 +92,14 @@ let test_zip32 () = assert (xsk.parent_fvk_tag = ba_of_hex "00000000") ; assert (xsk.child_index = ba_of_hex "00000000") ; assert (xsk.chain_code = v.c) ; - assert (xsk.expsk.ask = TzOption.unopt_assert ~loc:__POS__ v.ask) ; - assert (xsk.expsk.nsk = TzOption.unopt_assert ~loc:__POS__ v.nsk) ; + assert (xsk.expsk.ask = Stdlib.Option.get v.ask) ; + assert (xsk.expsk.nsk = Stdlib.Option.get v.nsk) ; assert (xsk.expsk.ovk = v.ovk) ; assert (xsk.dk = v.dk) ; let xfvk = of_sk xsk in assert (xfvk = v.xfvk) ; let (_j, address) = new_address xfvk default_index in - assert (address.diversifier = TzOption.unopt_assert ~loc:__POS__ v.d0) ; + assert (address.diversifier = Stdlib.Option.get v.d0) ; (* TODO continue test with derivation once implemented *) () diff --git a/src/lib_sapling/test/test_merkle.ml b/src/lib_sapling/test/test_merkle.ml index b169c02b6ed52b51706108d5f151f1f2ac4631d5..01e251581a31ad826637deb5975ce02578a3290e 100644 --- a/src/lib_sapling/test/test_merkle.ml +++ b/src/lib_sapling/test/test_merkle.ml @@ -300,10 +300,10 @@ let test_merkle3 () = assert (size t = Int64.succ pos) ; assert (get_cm t pos = Some cm) ; assert (get_root t = Core.Hash.uncommitted ~height:32) ; - let l = get_from t 0L |> TzOption.unopt_assert ~loc:__POS__ in + let l = get_from t 0L |> Stdlib.Option.get in assert (List.length l = Int64.to_int pos + 1) ; List.iter (fun e -> assert (e = cm)) l ; - let l = get_from t pos |> TzOption.unopt_assert ~loc:__POS__ in + let l = get_from t pos |> Stdlib.Option.get in assert (List.length l = 1) ; assert (List.hd l = cm) ; assert (get_from t (Int64.succ pos) = None) ; diff --git a/src/lib_sapling/test/test_sapling.ml b/src/lib_sapling/test/test_sapling.ml index 2600b6fb2c2a834e63df84ab384da921992e2589..7c610a228528193aaaca35b480c893c59e7355f8 100644 --- a/src/lib_sapling/test/test_sapling.ml +++ b/src/lib_sapling/test/test_sapling.ml @@ -9,9 +9,7 @@ let test_get_memo_size () = let rcm = Rcm.random () in let memo = Bytes.empty in let esk = DH.esk_random () in - let cv = - TzOption.unopt_assert ~loc:__POS__ (CV.of_bytes (Hacl.Rand.gen 32)) - in + let cv = Stdlib.Option.get (CV.of_bytes (Hacl.Rand.gen 32)) in let cm = Commitment.of_bytes_exn (Hacl.Rand.gen 32) in let epk = DH.derive_ephemeral address esk in let cipher = Ciphertext.encrypt 0L address vk rcm memo (cv, cm, epk) esk in @@ -27,20 +25,14 @@ let test_proof_raw () = let rcm = Rcm.random () in let xfvk = Viewing_key.of_sk xsk in let (_, address) = Viewing_key.(new_address xfvk default_index) in - let nf = - TzOption.unopt_assert ~loc:__POS__ - @@ Nullifier.compute address xfvk ~amount:vlue rcm ~position:pos - in - let cm = - TzOption.unopt_assert ~loc:__POS__ - @@ Commitment.compute address ~amount:vlue rcm - in + let nf = Nullifier.compute address xfvk ~amount:vlue rcm ~position:pos in + let cm = Commitment.compute address ~amount:vlue rcm in let esk = DH.esk_random () in let epk = DH.derive_ephemeral address esk in let tree = T.add T.empty [cm] in let root_alt = T.get_root tree in let root = root_alt in - let witness = TzOption.unopt_assert ~loc:__POS__ @@ T.get_witness tree 0L in + let witness = Stdlib.Option.get @@ T.get_witness tree 0L in let tohash = Bytes.make 32 '1' in let hash = Blake2B.( @@ -48,9 +40,7 @@ let test_proof_raw () = in let sighash = R.to_sighash hash in let ar = R.to_ar @@ R.generate_r () in - let signature = - TzOption.unopt_assert ~loc:__POS__ (R.spend_sig xsk.expsk.ask ar sighash) - in + let signature = R.spend_sig xsk.expsk.ask ar sighash in R.init_params () ; let ctx_prove = R.proving_ctx_init () in let ctx_verif = R.verification_ctx_init () in @@ -65,7 +55,6 @@ let test_proof_raw () = ~amount:vlue ~root ~witness - |> TzOption.unopt_assert ~loc:__POS__ in let check_spend = R.check_spend ctx_verif cv_spend root nf rk zkproof_spend signature sighash @@ -79,12 +68,8 @@ let test_proof_raw () = address.pkd rcm ~amount:vlue - |> TzOption.unopt_assert ~loc:__POS__ - in - let bindingsig = - TzOption.unopt_assert ~loc:__POS__ - @@ R.make_binding_sig ctx_prove ~balance:Int64.zero sighash in + let bindingsig = R.make_binding_sig ctx_prove ~balance:Int64.zero sighash in let check_output = R.check_output ctx_verif cv_output cm epk zkproof_output in @@ -116,10 +101,7 @@ let test_full_transaction () = let (_, addr3) = Viewing_key.(new_address xfvk3 default_index) in (* creation of the first note *) let rcm_1 = Rcm.random () in - let cm_1 = - Commitment.compute addr1 ~amount:10L rcm_1 - |> TzOption.unopt_assert ~loc:__POS__ - in + let cm_1 = Commitment.compute addr1 ~amount:10L rcm_1 in (* insertion of the first note in the merkle tree (ie. 1 created 10 out of thin air) *) let t_1 = T.add T.empty [cm_1] in (* ---------------1 transfers 10 to B--------------------- *) @@ -130,25 +112,19 @@ let test_full_transaction () = (* randomness for the created commitment which will belong to 2 *) (* commitment for 2 *) let rcm_2 = Rcm.random () in - let cm_2 = - Commitment.compute addr2 ~amount:10L rcm_2 - |> TzOption.unopt_assert ~loc:__POS__ - in + let cm_2 = Commitment.compute addr2 ~amount:10L rcm_2 in (* root of the current state of the blockchain *) let root_1 = T.get_root t_1 in (* witness to show that what we spend (cm_1) belongs to the current state of the blockchain in pos 0 *) - let witness_1 = TzOption.unopt_assert ~loc:__POS__ @@ T.get_witness t_1 0L in + let witness_1 = Stdlib.Option.get @@ T.get_witness t_1 0L in (* randomness to randomize the signature key *) let ar_1 = Proving.ar_random () in (* randomness for the key exchange done with 2 *) let esk_1 = DH.esk_random () in let epk_1 = DH.derive_ephemeral addr2 esk_1 in (* nullifier to 'destroy' cm_1 *) - let nf_1 = - Nullifier.compute addr1 xfvk1 ~amount:10L rcm_1 ~position:0L - |> TzOption.unopt_assert ~loc:__POS__ - in + let nf_1 = Nullifier.compute addr1 xfvk1 ~amount:10L rcm_1 ~position:0L in R.init_params () ; (* Creation of a context to kep track of some info *) let ctx_prove_1 = R.proving_ctx_init () in @@ -173,10 +149,7 @@ let test_full_transaction () = (* Hash of the spend description *) let sighash_2 = UTXO.hash_input cv_spend_1 nf_1 rk_1 zkproof_spend_1 key in (* Signature of the input *) - let signature_1 = - R.spend_sig xsk1.expsk.ask ar_1 sighash_2 - |> TzOption.unopt_assert ~loc:__POS__ - in + let signature_1 = R.spend_sig xsk1.expsk.ask ar_1 sighash_2 in (* encryption of the ciphertext *) let nonce_1 = Crypto_box.random_nonce () in let plaintext = @@ -218,10 +191,7 @@ let test_full_transaction () = sends the 10 he had to 2. The context ctx_prove has to be given in argument when we compute the output and spend proofs *) - let bindingsig_1 = - TzOption.unopt_assert ~loc:__POS__ - @@ R.make_binding_sig ctx_prove_1 ~balance:0L sighash_1 - in + let bindingsig_1 = R.make_binding_sig ctx_prove_1 ~balance:0L sighash_1 in (* The context can now be freed *) let () = R.proving_ctx_free ctx_prove_1 in (* 1 puts on the blockchain: @@ -263,28 +233,19 @@ let test_full_transaction () = (* 2 gets the root and the witness for position 1 (ie. for cm_2) from the new merkle tree *) let root_2 = T.get_root t_2 in - let witness_2 = TzOption.unopt_assert ~loc:__POS__ @@ T.get_witness t_2 1L in + let witness_2 = Stdlib.Option.get @@ T.get_witness t_2 1L in (* 2 gets a pkd and d from 3 and computes as before the necessary stuff *) let ar_2 = Proving.ar_random () in let esk_2 = DH.esk_random () in let epk_2 = DH.derive_ephemeral addr3 esk_2 in - let nf_2 = - Nullifier.compute addr2 xfvk2 ~amount:10L rcm_2 ~position:1L - |> TzOption.unopt_assert ~loc:__POS__ - in + let nf_2 = Nullifier.compute addr2 xfvk2 ~amount:10L rcm_2 ~position:1L in let ctx_prove_2 = R.proving_ctx_init () in let sighash_3 = R.to_sighash @@ Bytes.create 32 in let sighash_4 = R.to_sighash @@ Bytes.create 32 in (* Bytes.fill sighash_4 '1' ; *) - let signature_2 = - R.spend_sig xsk2.expsk.ask ar_2 sighash_4 - |> TzOption.unopt_assert ~loc:__POS__ - in + let signature_2 = R.spend_sig xsk2.expsk.ask ar_2 sighash_4 in let rcm_3 = Rcm.random () in - let cm_3 = - Commitment.compute addr3 ~amount:5L rcm_3 - |> TzOption.unopt_assert ~loc:__POS__ - in + let cm_3 = Commitment.compute addr3 ~amount:5L rcm_3 in (* the shared secret is here unnecessary since in our example 3 won't spend money It has to be done in real though *) let (cv_spend_2, rk_2, zkproof_spend_2) = @@ -298,7 +259,6 @@ let test_full_transaction () = ~amount:10L ~root:root_2 ~witness:witness_2 - |> TzOption.unopt_assert ~loc:__POS__ in let (cv_output_2, zkproof_output_2) = R.output_proof @@ -308,14 +268,10 @@ let test_full_transaction () = addr3.pkd rcm_3 ~amount:5L - |> TzOption.unopt_assert ~loc:__POS__ in (* Here we put 5, meaning 5 is getting out of the shielded pos_in A regular transaction will give 5 to an address *) - let bindingsig_2 = - TzOption.unopt_assert ~loc:__POS__ - @@ R.make_binding_sig ctx_prove_2 ~balance:5L sighash_3 - in + let bindingsig_2 = R.make_binding_sig ctx_prove_2 ~balance:5L sighash_3 in let () = R.proving_ctx_free ctx_prove_2 in (* The validator checks and updates the state *) let ctx_verif_2 = R.verification_ctx_init () in @@ -358,9 +314,7 @@ let test_forge () = Example.Validator.verify_update t1 state key >>=? fun (_, state) -> let forge_input_opt = Forge.Input.get state 0L vk1 in - let (_msg, forge_input) = - TzOption.unopt_assert ~loc:__POS__ forge_input_opt - in + let (_msg, forge_input) = Stdlib.Option.get @@ forge_input_opt in let forge_output = Forge.make_output addr2 10L Bytes.empty in let transaction = Forge.forge_transaction [forge_input] [forge_output] sk1 key state diff --git a/src/lib_sapling/tezos-sapling.opam b/src/lib_sapling/tezos-sapling.opam index 4d6ad12ad8d342b616b9f00cb704b3112be05101..949a540fd25d16280417ac21aa99561be5a00bbe 100644 --- a/src/lib_sapling/tezos-sapling.opam +++ b/src/lib_sapling/tezos-sapling.opam @@ -17,7 +17,6 @@ depends: [ "tezos-crypto" "tezos-stdlib" "tezos-error-monad" - "tezos-lwt-result-stdlib" { with-test } "alcotest-lwt" { with-test & >= "1.1.0" } ] build: [[ "dune" "build" "-j" jobs "-p" name "@install" ]] diff --git a/src/proto_008_PtEdoTez/lib_protocol/test/helpers/sapling_helpers.ml b/src/proto_008_PtEdoTez/lib_protocol/test/helpers/sapling_helpers.ml index 491efadc83a7b7fc4c06c6fa2fbfcbabda34bb9f..18334b69f67d55142ce23106584ae58d0541f9d5 100644 --- a/src/proto_008_PtEdoTez/lib_protocol/test/helpers/sapling_helpers.ml +++ b/src/proto_008_PtEdoTez/lib_protocol/test/helpers/sapling_helpers.ml @@ -101,7 +101,6 @@ module Common = struct let rcm = Tezos_sapling.Core.Client.Rcm.random () in let position = 10L in Tezos_sapling.Core.Client.Nullifier.compute addr vk ~amount rcm ~position - |> TzOption.unopt_assert ~loc:__POS__ let gen_cm_cipher ~memo_size () = let open Tezos_sapling.Core.Client in @@ -112,9 +111,7 @@ module Common = struct in let amount = 10L in let rcm = Tezos_sapling.Core.Client.Rcm.random () in - let cm = - Commitment.compute addr ~amount rcm |> TzOption.unopt_assert ~loc:__POS__ - in + let cm = Commitment.compute addr ~amount rcm in let cipher = let payload_enc = Data_encoding.Binary.to_bytes_exn diff --git a/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml index fa67ee776761bcd413ea6d1dc3869e025e3df8be..484aeff92b9d9bb30acaaf63af0ff816dffd05d6 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/sapling_helpers.ml @@ -101,7 +101,6 @@ module Common = struct let rcm = Tezos_sapling.Core.Client.Rcm.random () in let position = 10L in Tezos_sapling.Core.Client.Nullifier.compute addr vk ~amount rcm ~position - |> TzOption.unopt_assert ~loc:__POS__ let gen_cm_cipher ~memo_size () = let open Tezos_sapling.Core.Client in @@ -112,9 +111,7 @@ module Common = struct in let amount = 10L in let rcm = Tezos_sapling.Core.Client.Rcm.random () in - let cm = - Commitment.compute addr ~amount rcm |> TzOption.unopt_assert ~loc:__POS__ - in + let cm = Commitment.compute addr ~amount rcm in let cipher = let payload_enc = Data_encoding.Binary.to_bytes_exn