From 01ebf6b8cc09ef76ff0ffcac392af0689f39024e Mon Sep 17 00:00:00 2001 From: swrup Date: Wed, 25 Feb 2026 00:12:05 +0100 Subject: [PATCH] JJ: Description from the destination commit: wip: test revoke JJ: Description from source commit: fix secmod add --- keys.json | 1 + src/keys.ml | 24 ++++++++++++++++++++---- src/secmod_eddsa.ml | 18 +++++++++++++----- src/secmod_rsa.ml | 19 ++++++++++++++----- src/util.ml | 7 ++++++- test/offline_management.sh | 26 ++++++++++++++++++++++++++ tools/offline.ml | 18 ++++++++++++++++++ 7 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 keys.json diff --git a/keys.json b/keys.json new file mode 100644 index 00000000..2ec8a5e6 --- /dev/null +++ b/keys.json @@ -0,0 +1 @@ +{"version":"31:0:0","base_url":"http://localhost:3434/","currency":"KUDO","currency_specification":{"name":"euro","num_fractional_input_digits":2,"num_fractional_normal_digits":2,"num_fractional_trailing_zero_digits":2,"alt_unit_names":"{\"0\":\"€\",\"3\":\"k€\"}","common_amounts":[]},"stefan_abs":"KUDO:0.00","stefan_log":"KUDO:0.00","stefan_lin":0,"asset_type":"fiat","accounts":[],"wire_fees":{"x-taler-bank":[]},"wads":[],"rewards_allowed":false,"kyc_enabled":false,"disable_direct_deposit":false,"master_public_key":"SJ0NYND22VQP3MP7FM754RDX8HCKVWAXTHY9SQNBTPRJZ2SPM2S0","reserve_closing_delay":{"d_us":32756645000000},"hard_limits":[],"zero_limits":[],"denominations":[{"cipher":"RSA","denoms":[{"rsa_pub":"040000YGPE1C5Y99752NH0XYQMV9H9QYRXTSZXNX7RV17GA0048H3QFVXDE7JZNFJ06H1WRF2XBXQPB9HP8X3XWJHCA710Y361C8S7S0Z6JAH7TPB8AYG6729880MJYS91W6Z4GFPSDSC37DW90N412VGZ6KBAJDW8EKTWW7KVZ19TR2V74CHX6KARHQFHFW71M1699NP632AXER9X8W7E6M5HQFSRKKX9C411XEX9E53RTH3JYZ0QZMJF5DRW0MW0WMD2M25AVPJNMZTZ49NWXFAV5M8278RRDWSGYNRVRZ8QC0FY76ZM6HQRYB5AA9CCJPA8NQSWRQ80GN7P8GDWJK2037BX56W30KD9G64WHX22HZE2WSEJZ0XEJG581ZVXTKC6CRFBRTFK98J9BXV3GNB9XXVX8F04002","master_sig":"HTJGF9WNSB11Z2A9ZGH44929TG7PCV98DBTZG94SZV8P474XB0S3TE9W30XAAEYNTNVEFMKTHVK2X7S4BSX87DN6GVSJEDC05EFG03R","stamp_start":{"t_s":1771956512},"stamp_expire_withdraw":{"t_s":1803492512},"stamp_expire_deposit":{"t_s":1803492512},"stamp_expire_legal":{"t_s":1803492512},"lost":null}],"value":"KUDO:0.01","fee_withdraw":"KUDO:0.00","fee_deposit":"KUDO:0.00","fee_refresh":"KUDO:0.00","fee_refund":"KUDO:0.00"},{"cipher":"RSA","denoms":[{"rsa_pub":"040000WTPHV9A7MEHVQREK8DM5NK5RAWGBJDR11ZTD44J1NR15FVF49QGKTTTRJHNV1T30J528W96WEC2VW9S197KD1KS27BPMJY2QYS65SNC2ZCE7BSXBQTSXJCRDGC99P5QMXVMSKDJ9HZC7T9HP8A0NMBWHJD5HXYEB60A9DVDA9KT7G7VFE30G6MEAQHP3G718VYCYYKDCXXXG1ZYDNW086V87KSD2VVDG7FKK59T8PHEKPAXHYQE1ZK2ATSVM8RJ1KXGDRQ7HPVP1ED9VDMV31KHZTVP76XSYZ8DT38VRMGREAC9XVQBXPA5AZ6WXF1J42MXSX3BN5QWBGV47XT0M1EX6VWJ2ERM1NWJ1CAH4BTR9D6C1EZQ9VY8XT4FZBGQ5C712Y5GFTJZEV556XBCDQWWMJ904002","master_sig":"M3HXFNVA2Q5508DZ982G0BE93Y0DS8BNMRPBA0MV9Y2Y1FN519XB0ZAFDRNAM5Y9WD02PD4DW0P3646KQE5B63N5KCN2QRYEFS1ZY2G","stamp_start":{"t_s":1771956512},"stamp_expire_withdraw":{"t_s":1803492512},"stamp_expire_deposit":{"t_s":1803492512},"stamp_expire_legal":{"t_s":1803492512},"lost":null}],"value":"KUDO:0.02","fee_withdraw":"KUDO:0.00","fee_deposit":"KUDO:0.00","fee_refresh":"KUDO:0.00","fee_refund":"KUDO:0.00"}],"exchange_sig":"WMKRQD4YPV3ZMAGR74CDXETSXZ1KMAMTH5PWB1PC16Q768A4VX6B964VEWX29PFFRK8ER96YKDVPDGFATRE12TNYH12K8BY2CK0AA00","exchange_pub":"M03XWHRBKYGVS46TX33W2NCKBH8KMSTXP0N5PS4H3EDS3TB6KYQG","recoup":[],"global_fees":[{"start_date":{"t_s":0},"end_date":{"t_s":99999999},"history_fee":"KUDO:0.00","account_fee":"KUDO:0.00","purse_fee":"KUDO:0.00","history_expiration":{"d_us":9999999000000},"purse_account_limit":1,"purse_timeout":{"d_us":9999999000000},"master_sig":"291EH5PMTD5KCM35VPREXS7VY87RZXAZS0WMN7CFA1MH2G1H40YSAJZT72Q64EKD22F278AHK8R71QSV03YNRC56CMN1SJXPG11PP3G"}],"list_issue_date":{"t_s":1771956512},"auditors":[],"signkeys":[{"key":"M03XWHRBKYGVS46TX33W2NCKBH8KMSTXP0N5PS4H3EDS3TB6KYQG","stamp_start":{"t_s":1795540112},"stamp_expire":{"t_s":1797358112},"stamp_end":{"t_s":1827076112},"master_sig":"86FX5WY3H55NW5RQ03BMH662S673E5FKHGZ04VG165CEN2D6E92A643NCPJ3AGF1F440SCT1D80PW5KJE7Q3YB44B99KJEQWMRQ8C38"},{"key":"5TSCRN9PKQQ7ZCKV3F2BGW9A25MV8BZA2MCAFY5TTKCH8PCVBDPG","stamp_start":{"t_s":1799168912},"stamp_expire":{"t_s":1800986912},"stamp_end":{"t_s":1830704912},"master_sig":"67ZS3X61MQ7PADPM8PXHC07E60CZY83YDSYQATF9QE6KGHRN4PV53N3MH0MEGJKMW0AZ6KTJ8S32R4BFDQEZD84PHQW7H1XXVGXHM3R"},{"key":"F7PWEYX3BDQ69CC0JZHYJ26XD72S228FVMPAVC8BGSPJC3PKQB60","stamp_start":{"t_s":1786468112},"stamp_expire":{"t_s":1788286112},"stamp_end":{"t_s":1818004112},"master_sig":"HAJ6E51F1M0YDWAE2JWN47VZX0WFB8RQ41C3XHMRGA36DNPCX29WJK0H960KZ8AKG7GH0P0BYKQWXYYA9VQ8MN4TDCNQ0H490E50238"},{"key":"XZK0WFNZWVEW8FVVW81GHVT90WB9FZVX7RE35MAH0NJ9YDMWVD50","stamp_start":{"t_s":1777396112},"stamp_expire":{"t_s":1779214112},"stamp_end":{"t_s":1808932112},"master_sig":"HDW4B986MYHK8A2KZZS6ZA2X1JCCR8Y32XZBWE95ZXS9WDXRKFFPDZZ7TY81NXK5NGY6AHXEASVX4VDXG36KHFY19D06FEYHFSPTR0R"},{"key":"KTVX6FAEDR74F7XXY9TQNBR568CQ3YABZYN9E8PZ6617CFJQ58M0","stamp_start":{"t_s":1788282512},"stamp_expire":{"t_s":1790100512},"stamp_end":{"t_s":1819818512},"master_sig":"CM3WV5QQ9ZHMGQ572MS8W1216WMQTNXW5W6H926Q95YFE22S4EXE8190575C0C9WPD0X9B383V5Y7WJ6Q3JSQZ2CWCFW2XYZH9ZE61G"},{"key":"G0N9CJ8508T0J1XS20NAS14JD6CPT8Y2RH7E3TV7PAFC9S6AJBZ0","stamp_start":{"t_s":1782839312},"stamp_expire":{"t_s":1784657312},"stamp_end":{"t_s":1814375312},"master_sig":"YGBG48VC8AH3DDEZ2DMNVZG2H0RJ63J1G1PP62SAGSFMP6X1XA2P5V2BRM5R1FNCXDDD97121TG1G3NKR3Y4ZF425QC3YDKHZB72W3G"},{"key":"HVM04856V7FTZV9F7QHXG6F5E14CDAAYBCHFBM525GRS50ADF5DG","stamp_start":{"t_s":1797354512},"stamp_expire":{"t_s":1799172512},"stamp_end":{"t_s":1828890512},"master_sig":"68DTEAG19RB2CQPCAW5JFH1MKSKNMFAEYSE8WR768JAYVM8DXVDJSS1N91VJ27VV2TNF0HZM4TRKT1X0XX1MP19KJNNT6TGFSR34J0G"},{"key":"WZGDNY0P30PPWS5MHYNKFW7CH36Y84HGHD6GENZSGKPDSH5YFTPG","stamp_start":{"t_s":1771956512},"stamp_expire":{"t_s":1773770912},"stamp_end":{"t_s":1803492512},"master_sig":"Y97D86NJQ6M3SYYFE6KHXWDSRWPFH10YHGCFJKXR0ENDK9F7K1TGVPZR0KC4GFQA4ZCTPQSVYXSBM5X0EMWBHPPKHM8JV4DYS91MA3G"},{"key":"V1XCV9RNZH2VC36HJXR838C72X0FE9KQ0M62MWR75SDJAR8MN150","stamp_start":{"t_s":1793725712},"stamp_expire":{"t_s":1795543712},"stamp_end":{"t_s":1825261712},"master_sig":"R7QE402H0XQGZ18YN7XE6C16XPN8QSSSN5DG2N66AWVKJB77CAW5HACZ88ZTD1E8XXF3PJSJ4ZPEDY6DJCTKFSPC4J9WCW8JWD72620"},{"key":"H0EYJN13VHZMPAY8R10HYSWDKMWH709C99H8HG5A60P9RP8Y5QHG","stamp_start":{"t_s":1800983312},"stamp_expire":{"t_s":1802801312},"stamp_end":{"t_s":1832519312},"master_sig":"CMJMZJZY4AM973SAQ65S3SQSR508AGGRTQR86MRZBK3JT879QWK3E6HXBH5YK0FR343NBN8JKJ7SKZSKWM62ZRRN6AMAKF6WR8KWA0R"},{"key":"QGBWFDYMVSB4AQMC604AFWXYYW4JJ00NXDSM9NW8E09FRZEJ65ZG","stamp_start":{"t_s":1781024912},"stamp_expire":{"t_s":1782842912},"stamp_end":{"t_s":1812560912},"master_sig":"NZQYJ5HWRVGFWYP3NKKCKN2JRPCR2GWM7EM3Z2B41DMGS8SE1T906RP67731Z1XK8V3QKJHT9T5NHJ1REH3AC2E5B37GWPGSHEFNA28"},{"key":"6K080RCP803623ZR9BCVZVV6T8BN7EVYZREG5GTXYPB45JWMWXS0","stamp_start":{"t_s":1784653712},"stamp_expire":{"t_s":1786471712},"stamp_end":{"t_s":1816189712},"master_sig":"QGPXX9PB8V3NQGJK679Q0NGJV1F6NZ573C7V4W3MMZSDN02FG29CNP8KZRE5DNPJ0VZRP0V8TD2HW96N178ZVCGMN94917AWF5DQ01G"},{"key":"4GCS29QVAB895PT57TBREJ7Z2FEEQGQ39AAMM4C7TP8S01J9ZMW0","stamp_start":{"t_s":1790096912},"stamp_expire":{"t_s":1791914912},"stamp_end":{"t_s":1821632912},"master_sig":"RTNQVDAKKNGNS0EFC3BBVRZPN602A5724JW2V1AA1D83G442R8BVJWB3ESJZMPBDMA876F09AZR4CEWQ62Q7F46NN7ANQAQSJ5HAY3G"},{"key":"084TDXBFFJG9G6XA5DE2MT1TDHPTX8ZEFP2XWZCEF7KYY3V599T0","stamp_start":{"t_s":1791911312},"stamp_expire":{"t_s":1793729312},"stamp_end":{"t_s":1823447312},"master_sig":"D7KQ0JV2MA5T56JPQ6A5WH3XWGYDW9EERMTF1Q36XM3RRRNNNG7YQ4145SGYANXSQ6KZG5FX0BA0WXV4644SKEEFJ0FGYFJ0KXHEG2R"},{"key":"8BSSW879HRZR8K62F7Y76TZ0ZXTT0HBJ01Y1M93J8PHWKB6S8GHG","stamp_start":{"t_s":1779210512},"stamp_expire":{"t_s":1781028512},"stamp_end":{"t_s":1810746512},"master_sig":"KEBEZ37E8GYQ72H2MXZHW0G5E1V4T46J6X9TSYEYBXZVQ9DB42849EYE939PT61RPCGAP888Q1H12QRA29R0PK8GTGBC79H6BBZA03R"},{"key":"ZFNDDWYTZ3CBFJMGYDV0NK4GSVP989ARVNFKQ0X07Y6F0M7CJEG0","stamp_start":{"t_s":1775581712},"stamp_expire":{"t_s":1777399712},"stamp_end":{"t_s":1807117712},"master_sig":"ETF8E2YK7SNRGBE49PS5MSB9HHQS7900K33AQKGVAHP61EBANA2XY5TJRNNTM0YWNXJYD291QP0SMD5W8GMJ6340C2GPBF7466EV82R"},{"key":"DX5DEZJDKYASBW4MJBPH1JY4V02GVYZD2JYJC0595XQ49S9MVX5G","stamp_start":{"t_s":1773767312},"stamp_expire":{"t_s":1775585312},"stamp_end":{"t_s":1805303312},"master_sig":"75S35NQBA0FXMNA0PTGHAMHZZ9481B96NGVP5F9B3F9YT9J3HP5MD20B375DVZB895ZN6PSS3N3WPB506DAMYBSW6BBZ9JVMDQBCJ1R"},{"key":"Y767Q8H0XMNDRVWKX9WSZ65GQEZHR1FMESXX0NVQDD63R8KQ9D6G","stamp_start":{"t_s":1802797712},"stamp_expire":{"t_s":1804612112},"stamp_end":{"t_s":1834333712},"master_sig":"6J18XT2EBE31K4ZBNWM611VXN63ADQFYMWW93HCW8QXA4EXHYE875CNA8EYATDMYW35B977QSNAPQQE74ZSC5PY79HCY6BHBD7TGE10"}]} \ No newline at end of file diff --git a/src/keys.ml b/src/keys.ml index bb1b6b72..17ceda97 100644 --- a/src/keys.ml +++ b/src/keys.ml @@ -68,6 +68,7 @@ module Make (Conn : Pg.CONN) : S = struct m "some signkeys found in database are missing from secmod, \ (unclean database/secmod state?)"); + Logs.debug (fun m -> m "found %d active signkey(s)" (List.length l)); l let denominations () = @@ -84,9 +85,12 @@ module Make (Conn : Pg.CONN) : S = struct m "some denominations found in database are missing from secmod, \ (unclean database/secmod state?)"); + Logs.debug (fun m -> + m "found %d active denomination(s)" (List.length l)); l let make_future_sk (pub, (start, expire)) = + Logs.debug (fun m -> m "make_future_sk: `%s`" (EddsaPublicKey.to_b32 pub)); let open Time in let stamp_start = Timestamp.of_absolute start in let stamp_expire = Timestamp.of_absolute expire in @@ -113,6 +117,9 @@ module Make (Conn : Pg.CONN) : S = struct | Some v -> v let make_future_dn (h_pub, (section_name, pub, start)) = + Logs.debug (fun m -> + m "make_future_dn: `%s`" + (B32.encode @@ Hash.DenominationHash.to_octets h_pub)); let open Time in let Config.Coin. { @@ -257,8 +264,10 @@ module Make (Conn : Pg.CONN) : S = struct (* rebuild it *) let future_sk = make_future_sk (pub, (t1, t2)) in let sk = sk_of_future_sk future_sk master_sig in - let* () = Pg.insert_signkey conn sk |> unwrap_err_caqti in - Ok ()) + let+ () = Pg.insert_signkey conn sk |> unwrap_err_caqti in + Logs.info (fun m -> + m "certified signkey `%s`" (EddsaPublicKey.to_b32 sk.pub)); + ()) let certify_future_denomination h_pub master_sig = match Sm_rsa.find_key h_pub with @@ -272,8 +281,11 @@ module Make (Conn : Pg.CONN) : S = struct | None -> let future_dn = make_future_dn (h_pub, (section_name, pub, t1)) in let dn = dn_of_future_dn future_dn h_pub master_sig in - let* () = Pg.insert_denom conn dn |> unwrap_err_caqti in - Ok ()) + let+ () = Pg.insert_denom conn dn |> unwrap_err_caqti in + Logs.info (fun m -> + m "certified denomination `%s`" + (B32.encode @@ Hash.DenominationHash.to_octets dn.h_pub)); + ()) let revoke_signkey pub revoked_sig = let* opt = find_signkey pub in @@ -282,6 +294,7 @@ module Make (Conn : Pg.CONN) : S = struct let+ () = Pg.insert_signkey_revocation conn pub revoked_sig |> unwrap_err_caqti in + Logs.info (fun m -> m "revoked signkey `%s`" (EddsaPublicKey.to_b32 pub)); () let revoke_denomination h_pub revoked_sig = @@ -292,5 +305,8 @@ module Make (Conn : Pg.CONN) : S = struct Pg.insert_denomination_revocation conn dn.h_pub revoked_sig |> unwrap_err_caqti in + Logs.info (fun m -> + m "revoked denomination `%s`" + (B32.encode @@ Hash.DenominationHash.to_octets h_pub)); () end diff --git a/src/secmod_eddsa.ml b/src/secmod_eddsa.ml index 9aa95cd0..f6f21c28 100644 --- a/src/secmod_eddsa.ml +++ b/src/secmod_eddsa.ml @@ -57,11 +57,17 @@ let write_eddsa fpath priv = let write_key k = write_eddsa (key_fpath k) k.priv let delete_file fpath = - Log.debug (fun m -> m "(disabled) delete key file `%a`" Fpath.pp fpath); - (* TODO just to be safe~~ + (* check fpath just to be safe *) + let () = + let root = Fpath.v Cfg.key_dir in + if not @@ Fpath.is_rooted ~root fpath then + Fmt.failwith + "delete_file failure: file `%a` is not contained in secmod directory" + Fpath.pp fpath + in + Log.debug (fun m -> m "delete key file `%a`" Fpath.pp fpath); let+ () = Bos.OS.File.delete ~must_exist:true fpath |> unwrap_err_msg in -*) - Ok () + () let get_key_dir_contents dir = let* dir = Fpath.of_string dir |> unwrap_err_msg in @@ -178,6 +184,7 @@ module Make () = struct let add t1 t2 = let k = gen_key t1 t2 in Hashtbl.replace t.ht k.pub k; + let+ () = write_key k in () let delete pub = @@ -206,7 +213,8 @@ module Make () = struct let revoke pub = let* k = find pub in let* () = delete pub in - add k.t1 k.t2; Ok () + let* () = add k.t1 k.t2 in + Ok () let conv = fun { priv= _; pub; t1; t2 } -> (pub, (t1, t2)) let keys () = Hashtbl.to_seq_values t.ht |> List.of_seq |> List.map conv diff --git a/src/secmod_rsa.ml b/src/secmod_rsa.ml index fef265f1..4c07667f 100644 --- a/src/secmod_rsa.ml +++ b/src/secmod_rsa.ml @@ -100,11 +100,17 @@ let write_rsa fpath priv = let write_key k = write_rsa (key_fpath k) k.priv let delete_file fpath = - Log.debug (fun m -> m "(disabled) delete key file `%a`" Fpath.pp fpath); - (* TODO just to be safe~~ + (* check fpath just to be safe *) + let () = + let root = Fpath.v Cfg.key_dir in + if not @@ Fpath.is_rooted ~root fpath then + Fmt.failwith + "delete_file failure: file `%a` is not contained in secmod directory" + Fpath.pp fpath + in + Log.debug (fun m -> m "delete key file `%a`" Fpath.pp fpath); let+ () = Bos.OS.File.delete ~must_exist:true fpath |> unwrap_err_msg in -*) - Ok () + () let get_key_dir_contents dir_fpath = let* b = Bos.OS.Dir.create ~mode:0o700 dir_fpath |> unwrap_err_msg in @@ -252,6 +258,7 @@ module Make () = struct let add section_name t1 t2 = let k = gen_key ~section_name t1 t2 in Hashtbl.replace t.ht k.h_pub k; + let+ () = write_key k in () let sm_pub = t.sm_pub @@ -263,9 +270,11 @@ module Make () = struct data let revoke h_pub = + Log.debug (fun m -> + m "revoke `%s`" (DenominationHash.to_octets h_pub |> B32.encode)); let* k = find h_pub in let* () = delete h_pub in - add k.section_name k.t1 k.t2; + let* () = add k.section_name k.t1 k.t2 in Ok () let conv = diff --git a/src/util.ml b/src/util.ml index bf00cd53..07215a01 100644 --- a/src/util.ml +++ b/src/util.ml @@ -48,8 +48,13 @@ module Log_reporter = struct in { report } + let set_level_secmods lvl = + let secmod_srcs = [ Secmod_rsa.src; Secmod_eddsa.src ] in + List.iter (fun src -> Logs.Src.set_level src lvl) secmod_srcs; + () + let setup () = - (*Logs.Src.set_level Secmod_rsa.src (Some Logs.Debug);*) + (*set_level_secmods (Some Logs.Debug);*) let level = Some Logs.Info in Logs.set_level ~all:false level; Fmt_tty.setup_std_outputs ~style_renderer:`Ansi_tty ~utf_8:true (); diff --git a/test/offline_management.sh b/test/offline_management.sh index e8a22785..a907f859 100755 --- a/test/offline_management.sh +++ b/test/offline_management.sh @@ -22,6 +22,24 @@ offline_tool sign \ offline_tool upload --input $b --url $url"/management/keys" echo "[OK] /management/keys" +offline_tool download --output $a --url $url"/keys" +rsa_pub=$(jq -r '.denominations[0].denoms[0].rsa_pub' $a) +h_denom=$(dune exec offline -- hash64 $rsa_pub) +offline_tool revoke-denom \ +--master_key $master_key \ +--output $b \ +$h_denom +offline_tool upload --input $b --url $url"/management/denominations/"$h_denom"/revoke" +echo "[OK] /management/denominations/\$H_DENOM/revoke" + +pub=$(jq -r '.signkeys[0].key' $a) +offline_tool revoke-signkey \ +--master_key $master_key \ +--output $b \ +$pub +offline_tool upload --input $b --url $url"/management/signkeys/"$pub"/revoke" +echo "[OK] /management/signkeys/\$EXCHANGE_PUB/revoke" + offline_tool enable-auditor \ --master_key $master_key \ --output $b \ @@ -32,6 +50,8 @@ offline_tool enable-auditor \ offline_tool upload --input $b --url $url"/management/auditors" echo "[OK] /management/auditors" +# todo test disable auditor + offline_tool wire-fee \ --master_key $master_key \ --output $b \ @@ -56,3 +76,9 @@ offline_tool global-fees \ --purse_timeout 9999999 offline_tool upload --input $b --url $url"/management/global-fees" echo "[OK] /management/global-fees" + +# todo test enable wire +# todo test disable wire +# todo test drain +# todo test aml-officer +# todo test partners diff --git a/tools/offline.ml b/tools/offline.ml index 3991fb8a..4ee93d7f 100644 --- a/tools/offline.ml +++ b/tools/offline.ml @@ -137,6 +137,23 @@ let revoke_denom_cmd = let+ output = output and+ master_key = master_key and+ h_denom = h_denom in revoke_denom ~output ~master_key ~h_denom +(* just for tests... *) +let test_hash64_cmd = + let doc = + "Compute SHA-512, print output to stdout, input and output are \ + Crockford-base32 encoded" + in + let s = Arg.(required & pos 0 (some string) None & info []) in + Cmd.make (Cmd.info "hash64" ~doc) + @@ + let+ s = s in + match B32.decode s with + | Error e -> Error e + | Ok s -> + let h = Hash.DenominationHash.hash s in + let s = B32.encode (Hash.DenominationHash.to_octets h) in + Fmt.pr "%s@." s; Ok () + let revoke_signkey_cmd = let doc = "Revoke signkey." in let signkey = @@ -305,6 +322,7 @@ let cli = wire_fee_cmd; global_fees_cmd; drain_cmd; + test_hash64_cmd; ] let main () = Cmd.eval_result cli