From 54414fa4c2f354005d9b98e437076b4987e3b65f Mon Sep 17 00:00:00 2001 From: swrup Date: Sat, 22 Nov 2025 20:10:56 +0100 Subject: [PATCH] . --- src/bin_signature.ml | 2 +- src/bin_type.ml | 145 +++++++++++++++++-------------------------- src/crypto.ml | 30 ++++++++- src/management.ml | 1 - 4 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/bin_signature.ml b/src/bin_signature.ml index 5ff1db75..1d6af428 100644 --- a/src/bin_signature.ml +++ b/src/bin_signature.ml @@ -1,7 +1,7 @@ (* Packed Signature *) open Bin_type -open Bin_type.Alias +open Bin_type.Aliases (* EccSignaturePurpose *) module Purpose = struct diff --git a/src/bin_type.ml b/src/bin_type.ml index 8145e550..75d5fd5f 100644 --- a/src/bin_type.ml +++ b/src/bin_type.ml @@ -13,6 +13,7 @@ (from https://docs.taler.net/taler-developer-manual.html) *) (* TODO + - correctly handle endianness - check that our struct are well packed - it looks like Bin only define packed structs - we don't need to worry about struct having "P" suffix @@ -26,7 +27,8 @@ - outdated doc(?) - some missing struct documentation - - correctly handle endianness *) + - better way to have module aliases? + *) (* TODO hash and C(ancer)-terminated strings @@ -37,10 +39,6 @@ ! not strings that are raw-bytes-data-like ? only for "HashCode" and "ShortHashCode" *) -(* TODO - - no need to wrap types in records? - - roll back to functor mess to avoid type confusion - - or just have HashXX/BytesXX ? *) module Taler_signatures = Include.Taler_signatures open Crypto @@ -49,29 +47,15 @@ let int32_size = 4 let int64_size = 8 module Bytes_32 = struct - type t = { v: string } + type t = string - let of_octets v = - match String.length v = 32 with - | false -> Fmt.failwith "of_octets failure: data is not 32 bytes" - | true -> { v } - - let bin = - let open Bin in - record (fun v -> { v }) |+ field (bytes 32) (fun t -> t.v) |> sealr + let bin = Bin.bytes 32 end module Bytes_64 = struct - type t = { v: string } + type t = string - let of_octets v = - match String.length v = 64 with - | false -> Fmt.failwith "of_octets failure: data is not 64 bytes" - | true -> { v } - - let bin = - let open Bin in - record (fun v -> { v }) |+ field (bytes 64) (fun t -> t.v) |> sealr + let bin = Bin.bytes 64 end (* microseconds since the UNIX Epoch @@ -79,20 +63,14 @@ end module INT64 = struct type t = int64 - let bin = - let open Bin in - record Fun.id |+ field neint64 Fun.id |> sealr - + let bin = Bin.neint64 let of_ptime v = Util.ptime_to_int64 v end module INT64_NBO = struct type t = int64 - let bin = - let open Bin in - record Fun.id |+ field beint64 Fun.id |> sealr - + let bin = Bin.beint64 let of_ptime = Util.ptime_to_int64 end @@ -118,16 +96,7 @@ module TimestampNBO : Time_S = INT64_NBO module Hash_32 = struct type t = Digestif.SHA256.t - let bin = - let open Bin in - map (bytes 32) Digestif.SHA256.of_raw_string Digestif.SHA256.to_raw_string - - let hash s = - match String.length s = 32 with - | false -> - Fmt.failwith "SHA256 failure: data is not 32 bytes, instead is %d" - (String.length s) - | true -> Digestif.SHA256.(digest_string s) + let hash s = Digestif.SHA256.(digest_string s) let of_octets s = match String.length s = 32 with @@ -135,19 +104,16 @@ module Hash_32 = struct | true -> Digestif.SHA256.of_raw_string s let to_octets = Digestif.SHA256.to_raw_string + + let bin = + let open Bin in + map (bytes 32) of_octets to_octets end module Hash_64 = struct type t = Digestif.SHA512.t - let bin = - let open Bin in - map (bytes 64) Digestif.SHA512.of_raw_string Digestif.SHA512.to_raw_string - - let hash s = - match String.length s = 64 with - | false -> Fmt.failwith "SHA512 failure: data is not 64 bytes" - | true -> Digestif.SHA512.(digest_string s) + let hash s = Digestif.SHA512.(digest_string s) let of_octets s = match String.length s = 64 with @@ -155,16 +121,16 @@ module Hash_64 = struct | true -> Digestif.SHA512.of_raw_string s let to_octets = Digestif.SHA512.to_raw_string + + let bin = + let open Bin in + map (bytes 64) of_octets to_octets end (* Hash over string + '\0' *) module Hash_32_cstr = struct type t = Digestif.SHA256.t - let bin = - let open Bin in - map (bytes 32) Digestif.SHA256.of_raw_string Digestif.SHA256.to_raw_string - let hash s = let s = s ^ "\x00" in Digestif.SHA256.(digest_string s) @@ -175,15 +141,15 @@ module Hash_32_cstr = struct | true -> Digestif.SHA256.of_raw_string s let to_octets = Digestif.SHA256.to_raw_string + + let bin = + let open Bin in + map (bytes 32) of_octets to_octets end module Hash_64_cstr = struct type t = Digestif.SHA512.t - let bin = - let open Bin in - map (bytes 64) Digestif.SHA512.of_raw_string Digestif.SHA512.to_raw_string - let hash s = let s = s ^ "\x00" in Digestif.SHA512.(digest_string s) @@ -194,6 +160,10 @@ module Hash_64_cstr = struct | true -> Digestif.SHA512.of_raw_string s let to_octets = Digestif.SHA512.to_raw_string + + let bin = + let open Bin in + map (bytes 64) of_octets to_octets end module type Hash_S = sig @@ -205,9 +175,9 @@ module type Hash_S = sig val to_octets : t -> string end -module DenominationHash : Hash_S = Hash_64 module FullPaytoHash : Hash_S = Hash_32 module NormalizedPaytoHash : Hash_S = Hash_32 +module DenominationHash : Hash_S = Hash_64 module PrivateContractHash : Hash_S = Hash_64 module ExtensionsPolicyHash : Hash_S = Hash_64 module MerchantWireHash : Hash_S = Hash_64 @@ -217,29 +187,6 @@ module CoinPubHash : Hash_S = Hash_64 module OutputCommitmentHash : Hash_S = Hash_64 module HashPlanchetsP : Hash_S = Hash_64 -(* Keys *) -module PursePublicKey = Bytes_32 -module AuditorPublicKeyP = Bytes_32 -module ReservePublicKeyP = Bytes_32 -module ReservePrivateKeyP = Bytes_32 -module MerchantPublicKeyP = Bytes_32 -module MerchantPrivateKeyP = Bytes_32 -module TransferPublicKeyP = Bytes_32 -module TransferPrivateKeyP = Bytes_32 -module AmlOfficerPublicKeyP = Bytes_32 -module AmlOfficerPrivateKeyP = Bytes_32 -module ExchangePublicKeyP = Bytes_32 -module ExchangePrivateKeyP = Bytes_32 -module MasterPublicKeyP = Bytes_32 -module MasterPrivateKeyP = Bytes_32 -module MasterSignatureP = EddsaSignature -module CoinSpendPublicKeyP = Bytes_32 (* union *) -module CoinSpendPrivateKeyP = Bytes_32 (* union *) -module TokenPublicKeyP = Bytes_32 (* union *) -module ReserveSignatureP = Bytes_64 -module ExchangeSignatureP = Bytes_64 -module CoinSpendSignatureP = Bytes_64 - (* --- Various --- *) module TransferSecretP = Bytes_64 @@ -259,6 +206,7 @@ module PublicRefreshCoinNonceP = Bytes_64 module DenominationBlindingKeyP = Bytes_32 module RefreshCommitmentP = Bytes_64 +(* -- TODO better: -- *) module UUID = struct (* uint32t value[4]; *) type t = { value: string } @@ -314,9 +262,7 @@ let currency_len = 12 (* TODO missing doc found in src/include/taler/taler_amount_lib.h *) -(* note: added 'Bin_' preffix to avoid conflict with Amount - when opening Bin_type *) -module Bin_amount = struct +module AmountP = struct type t = { value: int64; fraction: int32; @@ -349,7 +295,32 @@ module AmountNBO = struct |> sealr end -(* keep this for reference? *) -module Alias = struct - module Amount = Bin_amount +(* TODO keep this? + some of those are actuall ecdhe, or union of eddsa|ecdhe *) +module Aliases = struct + (* TODO add Amount.bin *) + module Amount = AmountP + + (* - Keys - *) + module PursePublicKey = EddsaPublicKey + module AuditorPublicKeyP = EddsaPublicKey + module ReservePublicKeyP = EddsaPublicKey + module MerchantPublicKeyP = EddsaPublicKey + module TransferPublicKeyP = EddsaPublicKey + module AmlOfficerPublicKeyP = EddsaPublicKey + module ExchangePublicKeyP = EddsaPublicKey + module MasterPublicKeyP = EddsaPublicKey + module CoinSpendPublicKeyP = EddsaPublicKey + module TokenPublicKeyP = EddsaPublicKey + module ReservePrivateKeyP = EddsaPrivateKey + module MerchantPrivateKeyP = EddsaPrivateKey + module TransferPrivateKeyP = EddsaPrivateKey + module AmlOfficerPrivateKeyP = EddsaPrivateKey + module ExchangePrivateKeyP = EddsaPrivateKey + module MasterPrivateKeyP = EddsaPrivateKey + module CoinSpendPrivateKeyP = EddsaPrivateKey + module MasterSignatureP = EddsaSignature + module ReserveSignatureP = EddsaSignature + module ExchangeSignatureP = EddsaSignature + module CoinSpendSignatureP = EddsaSignature end diff --git a/src/crypto.ml b/src/crypto.ml index def4e1f3..f7bd9921 100644 --- a/src/crypto.ml +++ b/src/crypto.ml @@ -27,6 +27,32 @@ module EddsaPublicKey = struct let jsont = Jsont.of_of_string ~kind:"EddsaPublicKey" of_b32 ~enc:to_b32 end +module EddsaPrivateKey = struct + (* EdDSA and ECDHE public keys always point on Curve25519 + and represented using the standard 256 bits Ed25519 compact format, + converted to Crockford Base32. *) + open Mirage_crypto_ec.Ed25519 + + type t = priv + + let to_octets t = priv_to_octets t + let of_octets t = priv_of_octets t |> Result.get_ok + + let bin = + let open Bin in + map (bytes 32) of_octets to_octets + + let of_b32 s = + let open Syntax in + let* octets = B32.decode s in + match priv_of_octets octets with + | Error e -> Fmt.error "%a" Mirage_crypto_ec.pp_error e + | Ok priv -> Ok priv + + let to_b32 t = B32.encode (to_octets t) + let jsont = Jsont.of_of_string ~kind:"EddsaPrivateKey" of_b32 ~enc:to_b32 +end + module EddsaSignature : sig type t @@ -112,6 +138,8 @@ module RsaPublicKey = struct | true -> Ok () in fun s -> + Result.get_ok + @@ let open Syntax in let len = String.length s in let* () = check (len >= 4) in @@ -131,7 +159,7 @@ module RsaPublicKey = struct let of_b32 s = let open Syntax in let* s = B32.decode s in - let* v = of_octets s in + let v = of_octets s in let+ v = Rsa.pub ~n:v.n ~e:v.e |> unwrap_err_msg in v diff --git a/src/management.ml b/src/management.ml index 63d4076e..f743dd70 100644 --- a/src/management.ml +++ b/src/management.ml @@ -27,7 +27,6 @@ let mk_future_denom denom_key_signf let open Bin_signature.DenominationKeyAnnouncementPS in let h_denom_pub = h_pub in let h_section_name = Hash_64_cstr.hash section_name in - let _huhu = BlindedCoinHash.hash section_name in let anchor_time = TimeAbsoluteNBO.of_ptime stamp_start in let duration_withdraw = Ptime.diff stamp_start stamp_expire_withdraw