use Jsont.Error for unsupported CS denom + wip type binary signature

This commit is contained in:
swrup 2025-11-30 22:44:36 +01:00
parent 4568b1bd4c
commit eb56150120
6 changed files with 66 additions and 45 deletions

View file

@ -90,40 +90,42 @@ module RsaDenominationKey = struct
|> Jsont.Object.finish |> Jsont.Object.finish
end end
(* not acctually implemented *) (* ! Clause Schnorr cipher is not supported *)
module CSDenominationKey = struct module CSDenominationKey = struct
(* Clause Schnorr *)
type t = { type t = {
age_mask: int; age_mask: int;
cs_pub: string; cs_pub: B32.t;
} }
(* TODO B32.jsont *)
let b32_jsont = Jsont.of_of_string ~kind:"B32" B32.decode ~enc:B32.encode
let jsont = let jsont =
let make age_mask cs_pub = { age_mask; cs_pub } in let make age_mask cs_pub = { age_mask; cs_pub } in
let age_mask v = v.age_mask in let age_mask v = v.age_mask in
let cs_pub v = v.cs_pub in let cs_pub v = v.cs_pub in
Jsont.Object.map ~kind:"CSDenominationKey" make Jsont.Object.map ~kind:"CSDenominationKey" make
|> Jsont.Object.mem "age_mask" Jsont.int ~enc:age_mask |> Jsont.Object.mem "age_mask" Jsont.int ~enc:age_mask
|> Jsont.Object.mem "cs_pub" Jsont.string ~enc:cs_pub |> Jsont.Object.mem "cs_pub" b32_jsont ~enc:cs_pub
|> Jsont.Object.finish |> Jsont.Object.finish
end end
module DenominationKey = struct module DenominationKey = struct
type t = type t = Rsa of RsaDenominationKey.t
| Rsa of RsaDenominationKey.t (*| CS of CSDenominationKey.t*)
| CS of CSDenominationKey.t
let rsa v = Rsa v let to_octets = function Rsa denom -> RsaPublicKey.to_octets denom.rsa_pub
let cs v = CS v
let of_cs _v =
Jsont.Error.msg Jsont.Meta.none "CSDenominationKey are not supported"
let of_rsa v = Rsa v
let jsont = let jsont =
let open Jsont.Object in let open Jsont.Object in
let rsa = Case.map "RSA" RsaDenominationKey.jsont ~dec:rsa in let rsa = Case.map "RSA" RsaDenominationKey.jsont ~dec:of_rsa in
let cs = Case.map "CS" CSDenominationKey.jsont ~dec:cs in let cs = Case.map "CS" CSDenominationKey.jsont ~dec:of_cs in
let enc_case = function let enc_case = function Rsa v -> Case.value rsa v in
| Rsa v -> Case.value rsa v
| CS v -> Case.value cs v
in
let cases = Case.[ make rsa; make cs ] in let cases = Case.[ make rsa; make cs ] in
map ~kind:"DenominationKey" Fun.id map ~kind:"DenominationKey" Fun.id
|> case_mem "cipher" Jsont.string ~enc:Fun.id ~enc_case cases |> case_mem "cipher" Jsont.string ~enc:Fun.id ~enc_case cases
@ -171,7 +173,7 @@ module FutureDenom = struct
fee_deposit: Amount.t; fee_deposit: Amount.t;
fee_refresh: Amount.t; fee_refresh: Amount.t;
fee_refund: Amount.t; fee_refund: Amount.t;
denom_secmod_sig: EddsaSignature.t; denom_secmod_sig: Bin_signature.DenominationKeyAnnouncementPS.Sig.t;
} }
let jsont = let jsont =
@ -218,7 +220,9 @@ module FutureDenom = struct
|> mem "fee_deposit" Amount.jsont ~enc:fee_deposit |> mem "fee_deposit" Amount.jsont ~enc:fee_deposit
|> mem "fee_refresh" Amount.jsont ~enc:fee_refresh |> mem "fee_refresh" Amount.jsont ~enc:fee_refresh
|> mem "fee_refund" Amount.jsont ~enc:fee_refund |> mem "fee_refund" Amount.jsont ~enc:fee_refund
|> mem "denom_secmod_sig" EddsaSignature.jsont ~enc:denom_secmod_sig |> mem "denom_secmod_sig"
Bin_signature.DenominationKeyAnnouncementPS.Sig.jsont
~enc:denom_secmod_sig
|> finish |> finish
end end

View file

@ -88,7 +88,7 @@ module DenominationKeyAnnouncementPS = struct
(* TODO taler_signatures purpose (* TODO taler_signatures purpose
we use TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY instead here *) we use TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY instead here *)
(* purpose.purpose = TALER_SIGNATURE_SM_DENOMINATION_KEY *) (* purpose.purpose = TALER_SIGNATURE_SM_DENOMINATION_KEY *)
type t = { type r = {
h_denom_pub: DenominationHash.t; h_denom_pub: DenominationHash.t;
h_section_name: Hash_64_cstr.t; h_section_name: Hash_64_cstr.t;
anchor_time: TimeAbsoluteNBO.t; anchor_time: TimeAbsoluteNBO.t;
@ -107,6 +107,24 @@ module DenominationKeyAnnouncementPS = struct
|+ field TimeAbsoluteNBO.bin (fun t -> t.anchor_time) |+ field TimeAbsoluteNBO.bin (fun t -> t.anchor_time)
|+ field TimeRelativeNBO.bin (fun t -> t.duration_withdraw) |+ field TimeRelativeNBO.bin (fun t -> t.duration_withdraw)
|> sealr |> sealr
module type SIG = sig
type t
val sign : (string -> string) -> r -> t
val verify : (string -> msg:string -> bool) -> t -> r -> bool
val jsont : t Jsont.t
end
module Sig : SIG = struct
type t = string
let sign f r = f @@ Bin.to_string bin r
let verify f s r = f s ~msg:(Bin.to_string bin r)
(* TODO B32.jsont, for others types too *)
let jsont = Jsont.string
end
end end
module SigningKeyAnnouncementPS = struct module SigningKeyAnnouncementPS = struct

View file

@ -52,6 +52,7 @@ module EddsaSignature : sig
type t type t
val sign : key:Mirage_crypto_ec.Ed25519.priv -> string -> t val sign : key:Mirage_crypto_ec.Ed25519.priv -> string -> t
val sign_as_string : key:Mirage_crypto_ec.Ed25519.priv -> string -> string
val of_b32 : string -> (t, string) result val of_b32 : string -> (t, string) result
val to_b32 : t -> string val to_b32 : t -> string
val to_octets : t -> string val to_octets : t -> string
@ -81,6 +82,8 @@ end = struct
(* mirage_crypto: "The result is the concatenation of r and s, as specified in RFC 8032." *) (* mirage_crypto: "The result is the concatenation of r and s, as specified in RFC 8032." *)
Mirage_crypto_ec.Ed25519.sign ~key s Mirage_crypto_ec.Ed25519.sign ~key s
let sign_as_string ~key s = sign ~key s
let check_size t = let check_size t =
match String.length t = 64 with match String.length t = 64 with
| false -> Error "EddsaSignature: invalid string length" | false -> Error "EddsaSignature: invalid string length"

View file

@ -21,19 +21,18 @@ let mk_future_denom denom_key_signf
} : } :
Denomination.t) = Denomination.t) =
let denom_pub = let denom_pub =
DenominationKey.Rsa RsaDenominationKey.{ age_mask; rsa_pub= pub } DenominationKey.of_rsa RsaDenominationKey.{ age_mask; rsa_pub= pub }
in in
let denom_secmod_sig = let denom_secmod_sig =
let open Bin_type in
let open Bin_signature.DenominationKeyAnnouncementPS in let open Bin_signature.DenominationKeyAnnouncementPS in
let h_denom_pub = h_pub in let h_denom_pub = h_pub in
let h_section_name = Hash_64_cstr.hash section_name in let h_section_name = Bin_type.Hash_64_cstr.hash section_name in
let anchor_time = stamp_start in let anchor_time = stamp_start in
let duration_withdraw = let duration_withdraw =
Timestamp.diff stamp_start stamp_expire_withdraw |> Timestamp.of_span_exn Timestamp.diff stamp_start stamp_expire_withdraw |> Timestamp.of_span_exn
in in
let ps = { h_denom_pub; h_section_name; anchor_time; duration_withdraw } in Sig.sign denom_key_signf
ps |> Bin.to_string bin |> denom_key_signf { h_denom_pub; h_section_name; anchor_time; duration_withdraw }
in in
FutureDenom. FutureDenom.
{ {
@ -61,8 +60,9 @@ let mk_future_signkey signkey_signf
let duration = let duration =
Timestamp.diff stamp_start stamp_expire |> Timestamp.of_span_exn Timestamp.diff stamp_start stamp_expire |> Timestamp.of_span_exn
in in
let ps = { exchange_pub; anchor_time; duration } in { exchange_pub; anchor_time; duration }
ps |> Bin.to_string bin |> signkey_signf |> Bin.to_string bin
|> signkey_signf
in in
FutureSignKey. FutureSignKey.
{ key= pub; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig } { key= pub; stamp_start; stamp_expire; stamp_end; signkey_secmod_sig }
@ -74,7 +74,8 @@ let mk_future_keys_response (secmod_signkey : Secmod_signkey.t)
|> List.filter (fun k -> Option.is_none k.Denomination.master_sig) |> List.filter (fun k -> Option.is_none k.Denomination.master_sig)
|> List.map (fun denom -> |> List.map (fun denom ->
let signf s = let signf s =
Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s Crypto.EddsaSignature.sign_as_string
~key:secmod_denom.sm_key.Signkey.priv s
in in
mk_future_denom signf denom) mk_future_denom signf denom)
in in

View file

@ -15,11 +15,13 @@ let () =
in in
() ()
let get_ok = function Error e -> failwith e | Ok v -> v
let () = let () =
let open Api in let open Api in
let check jsont s = let check jsont s =
let encode v = encode jsont v |> Result.get_ok in let encode v = encode jsont v |> get_ok in
let decode v = decode jsont v |> Result.get_ok in let decode v = decode jsont v |> get_ok in
let ts = decode s in let ts = decode s in
let s' = encode ts in let s' = encode ts in
let ts' = decode s' in let ts' = decode s' in
@ -35,13 +37,14 @@ let () =
check_bad Timestamp.jsont {|{"t_s": "123456780"}|}; check_bad Timestamp.jsont {|{"t_s": "123456780"}|};
check_bad Timestamp.jsont {|{"t_s": "agagou"}|}; check_bad Timestamp.jsont {|{"t_s": "agagou"}|};
(* TODO use a valid rsa_pub value *) (* CS not implemented *)
(* check_bad DenominationKey.jsont
check DenominationKey.jsont
{|{"cipher": "RSA", "age_mask": 18, "rsa_pub": "agagouh"}|};
check DenominationKey.jsont
{|{"cipher": "CS", "age_mask": 18, "cs_pub": "ouhagag"}|}; {|{"cipher": "CS", "age_mask": 18, "cs_pub": "ouhagag"}|};
*)
(* TODO test with a valid rsa_pub value *)
(* TODO handle "rsa pub_of_octets failure" correctly *)
(* check_bad DenominationKey.jsont
{|{"cipher": "RSA", "age_mask": 18, "rsa_pub": "agagouh"}|}; *)
() ()
let () = let () =

View file

@ -19,20 +19,12 @@ let denom_signature ~master_key
(* TODO check sigs *) (* TODO check sigs *)
denom_secmod_sig= _; denom_secmod_sig= _;
} = } =
let pub_octets = let octets = DenominationKey.to_octets denom_pub in
let denom_pub = let h_denom_pub = HashCode.hash octets in
match denom_pub with
| Rsa v -> v
| CS _ -> Fmt.failwith "CS key types are not supported."
in
let pub = denom_pub.RsaDenominationKey.rsa_pub in
RsaPublicKey.to_octets pub
in
let h_denom_pub = HashCode.hash pub_octets in
let master_sig = let master_sig =
let open Bin_signature.DenominationKeyValidityPS in let open Bin_signature.DenominationKeyValidityPS in
let master = EddsaPrivateKey.(pub_of_priv master_key) in let master = EddsaPrivateKey.(pub_of_priv master_key) in
let denom_hash = DenominationHash.hash pub_octets in let denom_hash = DenominationHash.hash octets in
{ {
master; master;
start= stamp_start; start= stamp_start;