open Crypto open Api let verify_future_keys_response = let verify_future_denom ~sm_denom_pub FutureDenom. { section_name; value= _; stamp_start; stamp_expire_withdraw; stamp_expire_deposit= _; stamp_expire_legal= _; denom_pub; fee_withdraw= _; fee_deposit= _; fee_refresh= _; fee_refund= _; denom_secmod_sig; } = let h_denom_pub = DenominationHash.hash (DenominationKey.to_octets denom_pub) in let h_section_name = Hash.Cstring.H64.hash section_name in let anchor_time = stamp_start in let duration_withdraw = Timestamp.diff stamp_start stamp_expire_withdraw in let open Bin_sig.DenominationKeyAnnouncement in verify_f ~f:(EddsaSignature.verify ~key:sm_denom_pub) denom_secmod_sig { h_denom_pub; h_section_name; anchor_time; duration_withdraw } in let verify_future_signkey ~sm_signkey_pub FutureSignKey. { key; stamp_start; stamp_expire; stamp_end= _; signkey_secmod_sig } = let exchange_pub = key in let anchor_time = stamp_start in let duration = Timestamp.diff stamp_start stamp_expire in let open Bin_sig.SigningKeyAnnouncement in verify_f ~f:(EddsaSignature.verify ~key:sm_signkey_pub) signkey_secmod_sig { exchange_pub; anchor_time; duration } in fun our_master_public_key FutureKeysResponse. { future_denoms; future_signkeys; master_pub; denom_secmod_public_key; signkey_secmod_public_key; } -> let open Syntax in let* () = match master_pub = our_master_public_key with | false -> Fmt.error "master public key of the future key response does not match ours" | true -> Ok () in let* () = list_iter (verify_future_denom ~sm_denom_pub:denom_secmod_public_key) future_denoms in let* () = list_iter (verify_future_signkey ~sm_signkey_pub:signkey_secmod_public_key) future_signkeys in Ok () let mk_future_keys = let denom_signature ~master_key FutureDenom. { section_name= _; value; stamp_start; stamp_expire_withdraw; stamp_expire_deposit; stamp_expire_legal; denom_pub; fee_withdraw; fee_deposit; fee_refresh; fee_refund= _; denom_secmod_sig= _; } = let octets = DenominationKey.to_octets denom_pub in let h_denom_pub = DenominationHash.hash octets in let master_sig = let open Bin_sig.DenominationKeyValidity in let master = EddsaPrivateKey.(pub_of_priv master_key) in sign_f ~f:(EddsaSignature.sign ~key:master_key) { master; start= stamp_start; expire_withdraw= stamp_expire_withdraw; expire_spend= stamp_expire_deposit; expire_legal= stamp_expire_legal; value; fee_withdraw; fee_deposit; fee_refresh; denom_hash= h_denom_pub; } in DenomSignature.{ h_denom_pub; master_sig } in let signkey_signature ~master_key FutureSignKey. { key; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig= _ } = let master_sig = let open Bin_sig.ExchangeSigningKeyValidity in sign_f ~f:(EddsaSignature.sign ~key:master_key) { start= stamp_start; expire= stamp_expire; end_= stamp_end; signkey_pub= key; } in SignKeySignature.{ key; master_sig } in fun ~master_key FutureKeysResponse. { future_denoms; future_signkeys; master_pub= _; denom_secmod_public_key= _; signkey_secmod_public_key= _; } -> let denom_sigs = List.map (denom_signature ~master_key) future_denoms in let signkey_sigs = List.map (signkey_signature ~master_key) future_signkeys in MasterSignatures.{ denom_sigs; signkey_sigs }