mte/src/denomination.ml

186 lines
5 KiB
OCaml

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;
h_pub: denom_hash;
master_sig: Signatures.DenominationKeyValidity.t;
}
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
(* 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
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
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
let cmp_group =
let cmp_amount a b =
(* TODO amount *)
let open Amount in
match Int64.unsigned_compare a.value b.value with
| 0 -> Int32.unsigned_compare a.fraction b.fraction
| n -> n
in
fun (Rsa a) (Rsa b) -> cmp_amount a.value b.value
in
let l =
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
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= _;
}
->
let h_pub =
DenominationHash.hash (Crypto.RsaPublicKey.to_octets rsa_pub)
in
{
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