mte/src/denomination.ml

176 lines
4.7 KiB
OCaml
Raw Normal View History

2025-12-15 16:43:49 +01:00
open Crypto
type t = {
pub: rsa_pub;
value: Amount.t;
stamp_start: Timestamp.t;
stamp_expire_withdraw: Timestamp.t;
stamp_expire_deposit: Timestamp.t;
stamp_expire_legal: Timestamp.t;
fee_withdraw: Amount.t;
fee_deposit: Amount.t;
fee_refresh: Amount.t;
fee_refund: Amount.t;
age_mask: int;
2026-02-17 09:30:20 +01:00
h_pub: denom_hash;
master_sig: Signatures.DenominationKeyValidity.t;
2025-12-15 16:43:49 +01:00
}
2026-02-27 20:28:56 +01:00
let verify_denomination_key_validity ~key dn =
let open Signatures.DenominationKeyValidity in
verify key dn.master_sig
{
R.master= key;
start= dn.stamp_start;
expire_withdraw= dn.stamp_expire_withdraw;
expire_spend= dn.stamp_expire_deposit;
expire_legal= dn.stamp_expire_legal;
value= dn.value;
fee_withdraw= dn.fee_withdraw;
fee_deposit= dn.fee_deposit;
fee_refresh= dn.fee_refresh;
fee_refund= dn.fee_refund;
denom_hash= dn.h_pub;
}
let make_denom_group_sorted denominations =
let open Syntax in
2026-02-24 17:23:03 +01:00
(* use hashtbl to re-group denoms *)
let ht = Hashtbl.create 0xff in
List.iter
(fun coin ->
let open Config.Coin in
assert (coin.cipher = `RSA);
let k =
( coin.value,
coin.fee_withdraw,
coin.fee_deposit,
coin.fee_refresh,
coin.fee_refund )
in
let v = [] in
Hashtbl.replace ht k v)
Config.Coin.all_coins;
let+ () =
list_iter
(fun {
pub;
value;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
age_mask= _;
h_pub= _;
master_sig;
} ->
let k = (value, fee_withdraw, fee_deposit, fee_refresh, fee_refund) in
let v =
Api.RsaDenom.
{
rsa_pub= pub;
master_sig;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
lost= None;
}
in
2026-02-24 17:23:03 +01:00
match Hashtbl.find_opt ht k with
| None -> Error "denomination does not match any coin in configuration"
| Some l ->
Hashtbl.replace ht k (v :: l);
Ok ())
denominations
in
2026-02-24 17:23:03 +01:00
let l = Hashtbl.to_seq ht |> List.of_seq in
(* ! important for /keys .exchange_sig
each group must be ordered in _reverse_ chronological order
order of groups to compute hash, must be the same as the order
in /keys .denominations *)
let open Api in
let open DenomGroup in
let open RsaDenomGroup in
let open RsaDenom in
let cmp_denom b a = Timestamp.compare a.stamp_start b.stamp_start in
2026-03-03 10:45:39 +01:00
let cmp_group = fun (Rsa a) (Rsa b) -> Amount.compare a.value b.value in
let l =
2026-02-24 17:23:03 +01:00
l
|> List.map
(fun
((value, fee_withdraw, fee_deposit, fee_refresh, fee_refund), denoms)
->
Rsa
{
denoms= List.sort cmp_denom denoms;
value;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
})
|> List.sort cmp_group
in
l
2026-02-27 17:49:54 +01:00
let denoms_of_denomgroups l =
let open Api in
l
|> List.concat_map
(fun
(DenomGroup.Rsa
RsaDenomGroup.
{
denoms;
value;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
})
->
let open RsaDenom in
denoms
|> List.map
(fun
{
rsa_pub;
master_sig;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
lost= _;
}
->
2026-02-27 23:36:05 +01:00
let h_pub = DenominationHash.hash_of_rsa rsa_pub in
2026-02-27 17:49:54 +01:00
{
pub= rsa_pub;
value;
stamp_start;
stamp_expire_withdraw;
stamp_expire_deposit;
stamp_expire_legal;
fee_withdraw;
fee_deposit;
fee_refresh;
fee_refund;
age_mask= 0;
h_pub;
master_sig;
}))
let hash_over_master_sigs denominations =
denominations
|> List.map (fun (Api.DenomGroup.Rsa g) -> g.Api.RsaDenomGroup.denoms)
|> List.concat_map (List.map (fun dn -> dn.Api.RsaDenom.master_sig))
|> List.map Signatures.DenominationKeyValidity.to_octets
|> String.concat ""
|> Hash.H64.hash