@adapt-toolkit/mufl 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +172 -0
  2. package/LICENSE.fsl +105 -0
  3. package/NOTICE +25 -0
  4. package/README.md +70 -0
  5. package/bin/mufl-compile.js +4 -0
  6. package/bin/mufl.js +4 -0
  7. package/lib/launcher.js +60 -0
  8. package/lib/paths.js +26 -0
  9. package/meta/meta.mm +2666 -0
  10. package/mufl_stdlib/config.mufl +86 -0
  11. package/mufl_stdlib/continuation.mm +51 -0
  12. package/mufl_stdlib/control_packet.mu +184 -0
  13. package/mufl_stdlib/cryptography/address_document.mm +333 -0
  14. package/mufl_stdlib/cryptography/address_document_types.mm +16 -0
  15. package/mufl_stdlib/cryptography/attestation/attestation_document.mm +68 -0
  16. package/mufl_stdlib/cryptography/attestation/config.mufl +12 -0
  17. package/mufl_stdlib/cryptography/attestation/container_associated_data.mm +12 -0
  18. package/mufl_stdlib/cryptography/attestation/control_packet_identity_proof_document.mm +36 -0
  19. package/mufl_stdlib/cryptography/attestation/identity_proof_document_impl.mm +57 -0
  20. package/mufl_stdlib/cryptography/attestation/identity_proof_document_types.mm +45 -0
  21. package/mufl_stdlib/cryptography/attestation/node_description.mm +9 -0
  22. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/browser/browser_attestation_document.mm +25 -0
  23. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/browser/config.mufl +12 -0
  24. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/config.mufl +12 -0
  25. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/native/config.mufl +12 -0
  26. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/native/native_attestation_document.mm +25 -0
  27. package/mufl_stdlib/cryptography/attestation/platform_dependent_attestation_document/platform_dependent_attestation_document.mm +57 -0
  28. package/mufl_stdlib/cryptography/authorizing_container.mm +21 -0
  29. package/mufl_stdlib/cryptography/config.mufl +12 -0
  30. package/mufl_stdlib/cryptography/encrypted_channel.mm +95 -0
  31. package/mufl_stdlib/cryptography/key_storage.mm +391 -0
  32. package/mufl_stdlib/cryptography/key_storage_api.mm +17 -0
  33. package/mufl_stdlib/cryptography/key_utils.mm +20 -0
  34. package/mufl_stdlib/cryptography/peer_container.mu +17 -0
  35. package/mufl_stdlib/cryptography/registration_proof.mm +40 -0
  36. package/mufl_stdlib/current_transaction_info.mm +78 -0
  37. package/mufl_stdlib/identity_proof_document.mm +21 -0
  38. package/mufl_stdlib/integration_test_api.mm +39 -0
  39. package/mufl_stdlib/lists.mm +84 -0
  40. package/mufl_stdlib/permissions.mm +219 -0
  41. package/mufl_stdlib/platform_type_id.mm +20 -0
  42. package/mufl_stdlib/random.mm +50 -0
  43. package/mufl_stdlib/rslt.mm +32 -0
  44. package/mufl_stdlib/transaction_message_decoder.mm +22 -0
  45. package/mufl_stdlib/transaction_queue.mm +60 -0
  46. package/mufl_stdlib/vector.mm +115 -0
  47. package/mufl_stdlib/verification.mm +35 -0
  48. package/package.json +43 -0
  49. package/prebuilds/linux-x64/mufl +0 -0
  50. package/prebuilds/linux-x64/mufl-compile +0 -0
  51. package/transactions/__t_wrapper.mm +169 -0
  52. package/transactions/config.mufl +22 -0
  53. package/transactions/transaction.mm +200 -0
@@ -0,0 +1,169 @@
1
+ // This library defines a wrapper around a transaction function.
2
+ // The goal is that given a function that takes a MUFL record type
3
+ // to create a function that takes a string that contains JSON that encodes the value of that type
4
+ // and performs all the necessary runtime checks.
5
+
6
+ library __t_wrapper loads libraries transaction, key_storage, transaction_queue, identity_proof_document_types {
7
+
8
+ metadef t_trn: ($name->str, $targ->any).
9
+ metadef t_trn_extended: ($trn->t_trn, $is_signed->bool, $is_encrypted->bool).
10
+ metadef t_trn_message_info: (
11
+ $decoded_envelope -> transaction::envelope::external::decoded_type || t_trn,
12
+ $decoded_message -> t_trn,
13
+ $is_signed -> bool,
14
+ $is_encrypted -> bool,
15
+ $has_envelope -> bool
16
+ ).
17
+
18
+ hidden {
19
+ decrypt_message = fn (message: crypto_message) -> any {
20
+ return key_storage::decrypt_message message.
21
+ }
22
+
23
+ check_signature = fn (signature: crypto_signature, message: any) -> bool {
24
+ hash = _value_id message |.
25
+ return key_storage::check_signature hash signature.
26
+ }
27
+
28
+ check_origin_binding = fn (envelope: any) -> publickey_sign {
29
+ ip_raw = envelope $ip_document.
30
+ abort "Missing identity document on external message" WHEN ip_raw == NIL.
31
+ ip = ip_raw SAFE(identity_proof_document_types::t_identity_proof_document) abort "Invalid identity proof document" WHEN IS NIL.
32
+ identity = ip? $node_description $address_document $identity.
33
+ abort "Identity does not commit to the origin address" WHEN (identity $container_id) != (envelope $from).
34
+ sign_key_id = identity $default_keys $SIGN.
35
+ sign_pub IS publickey_sign+ = NIL.
36
+ sc identity $key_list -- (k->) {
37
+ if _crypto_get_key_id k == sign_key_id {
38
+ sign_pub -> k SAFE(publickey_sign).
39
+ break.
40
+ }
41
+ }
42
+ abort "SIGN key not found in identity key_list" WHEN sign_pub == NIL.
43
+ abort "Origin address does not commit to signing key" WHEN (key_storage::address_of_key sign_pub?) != (envelope $from).
44
+ return sign_pub?.
45
+ }
46
+
47
+ decode_message_with_keys = fn (message: any, origin_sign_key: publickey_sign+) -> t_trn_extended {
48
+ if message $encrypted_message {
49
+ is_ptsignature IS bool = TRUE.
50
+ signature IS crypto_signature+ = NIL.
51
+ if (message $ptsignature) {
52
+ signature -> (message $ptsignature) SAFE(crypto_signature).
53
+ } else {
54
+ signature -> (message $emsignature) SAFE(crypto_signature).
55
+ is_ptsignature -> NIL.
56
+ }
57
+ encrypted_message = (message $encrypted_message) SAFE(crypto_message).
58
+ decrypted_message = decrypt_message encrypted_message.
59
+ res = decrypted_message SAFE(t_trn).
60
+ if is_ptsignature && (check_signature signature? decrypted_message) {
61
+ return ($trn -> res, $is_signed -> TRUE, $is_encrypted -> TRUE).
62
+ } elif (!is_ptsignature && check_signature signature? encrypted_message) {
63
+ return ($trn -> res, $is_signed -> TRUE, $is_encrypted -> TRUE).
64
+ } else {
65
+ abort "Signature verification failed." WHEN TRUE.
66
+ return ($trn -> ($name -> "", $targ -> NIL), $is_signed -> FALSE, $is_encrypted -> FALSE).
67
+ }
68
+ } elif message $trn {
69
+ tn = message $trn.
70
+ signature = (message $ptsignature) SAFE(crypto_signature) abort "Missing field 'ptsignature' in signed message." WHEN IS NIL.
71
+ if origin_sign_key {
72
+ abort "Signature verification failed for message." WHEN ((_crypto_verify_hash_signature (_value_id tn |) signature? origin_sign_key?) != TRUE).
73
+ } else {
74
+ abort "Signature verification failed for message." WHEN ((check_signature signature? tn) == NIL).
75
+ }
76
+ return ($trn -> (tn safe(t_trn)), $is_signed -> TRUE, $is_encrypted -> FALSE).
77
+ } else {
78
+ return ($trn -> (message safe(t_trn)), $is_signed -> FALSE, $is_encrypted -> FALSE).
79
+ }
80
+ }
81
+ }
82
+
83
+ fn decode_message (message: any) -> t_trn_extended
84
+ {
85
+ return decode_message_with_keys message NIL.
86
+ }
87
+
88
+ /*
89
+ This function processing the input transaction envelope.
90
+ There are different types of transaction envelopes possible (you can learn more about different transaction types in transaction.mm):
91
+
92
+ 1. External envelope
93
+ ($from -> global_id, $to -> global_id, $ip_document -> identity_proof_document::type, $body -> ::transaction::type)
94
+
95
+ External envelopes then differ in body type
96
+ 1.1. signed encrypted
97
+ 1.2. signed
98
+ 1.3. unsigned unencrypted
99
+
100
+ 2. Internal envelope
101
+ ($name -> str, $targ -> any)
102
+
103
+
104
+ Function steps:
105
+ 1. Extract a message from the envelope if needed
106
+ 2. Decode the message if needed
107
+ 3. Set the flags
108
+ 4. Set the decoded message to the envelope if needed
109
+ 5. Set flags
110
+ */
111
+ fn process_transaction_envelope (envelope: any) -> t_trn_message_info {
112
+ has_envelope is bool = FALSE.
113
+ message is any = NIL.
114
+ origin_sign_key IS publickey_sign+ = NIL.
115
+
116
+ // This is the case of external message packed into the transaction envelope
117
+ if envelope $body != NIL {
118
+ origin_sign_key -> check_origin_binding envelope.
119
+ message -> envelope $body.
120
+ has_envelope -> TRUE.
121
+ } else {
122
+ message -> envelope.
123
+ has_envelope -> FALSE.
124
+ }
125
+
126
+ decode_message_with_keys message origin_sign_key => ($trn -> decoded_message, $is_signed -> is_signed, $is_encrypted -> is_encrypted).
127
+
128
+ abort "Unsigned external message rejected: enveloped messages must be signed." WHEN has_envelope && (!is_signed).
129
+
130
+ if has_envelope {
131
+ envelope $body -> decoded_message.
132
+ return (
133
+ $decoded_envelope -> envelope,
134
+ $decoded_message -> decoded_message,
135
+ $is_signed -> is_signed,
136
+ $is_encrypted -> is_encrypted,
137
+ $has_envelope -> has_envelope
138
+ ) safe t_trn_message_info.
139
+ } else {
140
+ return (
141
+ $decoded_envelope -> decoded_message,
142
+ $decoded_message -> decoded_message,
143
+ $is_signed -> is_signed,
144
+ $is_encrypted -> is_encrypted,
145
+ $has_envelope -> has_envelope
146
+ ) safe t_trn_message_info.
147
+ }
148
+ }
149
+
150
+ generic module __w takes TFunc {
151
+ __functor_mufl = fn (T:TFunc, _is_readonly: bool) -> (?T/reducer->transaction::envelope::type->any) {
152
+ return fn (message: (?T/reducer), envelope:transaction::envelope::type, origin: transaction::envelope::origin::type, is_signed: bool, is_encrypted: bool, timestamp: time) -> any {
153
+ transaction::set_current envelope is_signed is_encrypted origin timestamp.
154
+ ret = (T message SAFE( ?T/reducer )).
155
+ if _typeof ret == "IMMUTABLE_DICTIONARY" && ret $result_kind == transaction::results::kind::success {
156
+ buffered_actions = transaction_queue::get << transaction::envelope::get_trn_name envelope.
157
+ actions = ret $result.
158
+ sc buffered_actions -- ( -> action) {
159
+ actions (_count actions|) -> action as (transaction::action::type).
160
+ }
161
+ ret $result -> actions.
162
+
163
+ }
164
+ transaction::reset_current ().
165
+ return ret.
166
+ }
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,22 @@
1
+ config script {
2
+ (
3
+ $exports->(
4
+ $libraries->(
5
+ $transaction->#"transaction.mm",
6
+ $__t_wrapper->#"__t_wrapper.mm",
7
+ ),
8
+ $applications->(,),
9
+ ),
10
+ $imports->(
11
+ $libraries->(
12
+ $transaction->#"transaction.mm",
13
+ $__t_wrapper->#"__t_wrapper.mm",
14
+ $key_storage->#"../mufl_stdlib",
15
+ $transaction_queue->#"../mufl_stdlib",
16
+ $key_utils->#"../mufl_stdlib",
17
+ $identity_proof_document_types->#"../mufl_stdlib"
18
+ ),
19
+ $applications->(,)
20
+ )
21
+ ).
22
+ }
@@ -0,0 +1,200 @@
1
+ library transaction loads libraries key_utils, key_storage, identity_proof_document_types {
2
+ using key_utils.
3
+
4
+
5
+ generic module typedef takes T { metadef type: T. }
6
+ // generic module functor takes _Reducer, _Product
7
+ // {
8
+ // metadef type: _Product.
9
+ // metadef func_type: _Reducer->_Product.
10
+ // hidden
11
+ // {
12
+ // __func
13
+ // }
14
+ // }
15
+
16
+ metadef unsigned_message: ($name -> str, $targ -> any).
17
+ metadef signed_message: ($trn -> unsigned_message, $ptsignature -> crypto_signature).
18
+ metadef encrypted_pt_signed_message: ($encrypted_message -> crypto_message, $ptsignature -> crypto_signature).
19
+ metadef encrypted_em_signed_message: ($encrypted_message -> crypto_message, $emsignature -> crypto_signature).
20
+ metadef encrypted_signed_message: encrypted_pt_signed_message || encrypted_em_signed_message.
21
+ metadef type: (unsigned_message || signed_message || encrypted_pt_signed_message || encrypted_em_signed_message).
22
+
23
+
24
+ module envelope
25
+ {
26
+ module origin
27
+ {
28
+ user is <$user> = $user.
29
+ local is <$local> = $local.
30
+ external is <$external> = $external.
31
+ metadef type: ?user || ?local || ?external.
32
+ }
33
+ module external {
34
+ metadef type: (
35
+ $ip_document -> any,
36
+ $from -> global_id,
37
+ $to -> global_id,
38
+ $body -> ::transaction::type
39
+ ).
40
+
41
+ metadef decoded_type: (
42
+ $ip_document -> any,
43
+ $from -> global_id,
44
+ $to -> global_id,
45
+ $body -> unsigned_message
46
+ ).
47
+ }
48
+
49
+ module user instantiates typedef with unsigned_message.
50
+ module local instantiates typedef with unsigned_message.
51
+
52
+ metadef type: (external::type || user::type || local::type).
53
+
54
+ get_trn_name = fn (envelope) -> str {
55
+ if envelope $name {
56
+ return (envelope $name) as str.
57
+ }
58
+ return (envelope $body $name) as str.
59
+ }
60
+ }
61
+
62
+ module action {
63
+ module kind {
64
+ return_data is <$RET> = $RET.
65
+ verify is <$VER> = $VER.
66
+ send is <$SEND> = $SEND.
67
+ timeout is <$TIMEOUT> = $TIMEOUT.
68
+ metadef type: ?return_data || ?verify || ?send || ?timeout.
69
+ }
70
+
71
+ metadef return_data_t: ($action_kind -> ?kind::return_data, $data -> any, $req_id -> str+).
72
+ metadef send_t: ($action_kind -> ?kind::send, $data -> envelope::external::type).
73
+ metadef verify_t: ($action_kind -> ?kind::verify, $data -> ($verification_id -> global_id, $data -> any)).
74
+ metadef timeout_t: ($action_kind -> ?kind::timeout, $data -> ($continuation_id -> global_id, $seconds -> int)).
75
+
76
+ metadef type: return_data_t || send_t || verify_t || timeout_t.
77
+
78
+ return_data = fn (data: any) -> return_data_t
79
+ {
80
+ return ($action_kind -> kind::return_data, $data -> data).
81
+ }
82
+
83
+ hidden {
84
+ sign = fn (_:($trn -> tn: ($name -> str, $targ -> any))) -> signed_message {
85
+ signature = key_storage::default_sign (_value_id tn |).
86
+ return ($trn -> tn, $ptsignature -> signature) as signed_message.
87
+ }
88
+ }
89
+
90
+ send = fn (recipient: global_id, trn_body: transaction::type) -> send_t
91
+ {
92
+ body is transaction::type = trn_body.
93
+ // Discriminate the union by probing the distinguishing field first
94
+ // (cf. __t_wrapper::decode_message_with_keys): SAFE-casting an
95
+ // ENCRYPTED member against unsigned_message aborts in the meta
96
+ // domain check ($name reduces NIL against str) instead of yielding
97
+ // NIL, which broke every encrypted send. Only a plain UNSIGNED
98
+ // body (has $name, no signature wrapper) gets auto-signed here.
99
+ raw is any = trn_body.
100
+ if raw $name {
101
+ as_unsigned IS unsigned_message+ = trn_body SAFE(unsigned_message).
102
+ if as_unsigned {
103
+ body -> sign ($trn -> as_unsigned?).
104
+ }
105
+ }
106
+ my_ipd = identity_proof_document_types::get_my_ipd().
107
+ envelope is envelope::external::type = (
108
+ $ip_document -> my_ipd,
109
+ $from -> _get_container_id(),
110
+ $to -> recipient,
111
+ $body -> body).
112
+ return ($action_kind -> kind::send, $data -> envelope).
113
+ }
114
+
115
+ verify = fn (verification_id: global_id, data: any) -> verify_t
116
+ {
117
+ return ($action_kind -> kind::verify, $data -> ($verification_id -> verification_id, $data -> data)).
118
+ }
119
+
120
+ timeout = fn (continuation_id: global_id, seconds: int) -> timeout_t
121
+ {
122
+ return ($action_kind -> kind::timeout, $data -> ($continuation_id -> continuation_id, $seconds -> seconds)).
123
+ }
124
+
125
+ }
126
+
127
+ module results {
128
+ module kind {
129
+ success is <$SUC> = $SUC.
130
+ failure is <$FAIL> = $FAIL.
131
+
132
+ metadef type: ?success || ?failure.
133
+ }
134
+
135
+ module success instantiates typedef with ($result_kind -> ?kind::success, $result -> action::type[]).
136
+ module failure instantiates typedef with ($result_kind -> ?kind::failure, $result -> str).
137
+ metadef type: success::type || failure::type.
138
+ }
139
+
140
+ hidden {
141
+ current is envelope::type+ = NIL.
142
+ m_is_signed is bool = NIL.
143
+ m_is_encrypted is bool = NIL.
144
+ m_origin is envelope::origin::type+ = NIL.
145
+ m_timestamp is time+ = NIL.
146
+ }
147
+
148
+ set_current = fn (data: envelope::type+, is_signed: bool, is_encrypted: bool, origin: envelope::origin::type+, timestamp: time+)
149
+ {
150
+ current->data.
151
+ m_is_signed -> is_signed.
152
+ m_is_encrypted -> is_encrypted.
153
+ m_origin -> origin.
154
+ m_timestamp -> timestamp.
155
+ }
156
+
157
+ reset_current = fn _
158
+ {
159
+ set_current NIL NIL NIL NIL NIL.
160
+ }
161
+
162
+ get_transaction_time = fn _ = m_timestamp.
163
+
164
+ get_current = fn (_) = current.
165
+
166
+ is_signed = fn _ = m_is_signed.
167
+
168
+ is_encrypted = fn _ = m_is_encrypted.
169
+
170
+ get_origin = fn _ = m_origin.
171
+
172
+ failure = fn (message:str) -> results::failure::type
173
+ {
174
+ return ($result_kind -> results::kind::failure, $result -> message).
175
+ }
176
+
177
+ success = fn (actions: action::type[]) -> results::success::type
178
+ {
179
+ return ($result_kind -> results::kind::success, $result -> actions).
180
+ }
181
+
182
+ encrypt = fn (_:($cid -> cid: t_container_id, $trn -> tn: ($name -> str, $targ -> any), $isemsignature -> isem: bool)
183
+ ) -> encrypted_signed_message
184
+ {
185
+ encrypted_data = key_storage::default_encrypt tn cid.
186
+ if isem {
187
+ signature = key_storage::default_sign (_value_id encrypted_data |).
188
+ return ($encrypted_message -> encrypted_data, $emsignature -> signature) as encrypted_em_signed_message.
189
+ } else {
190
+ signature = key_storage::default_sign (_value_id tn |).
191
+ return ($encrypted_message -> encrypted_data, $ptsignature -> signature) as encrypted_pt_signed_message.
192
+ }
193
+ }
194
+
195
+
196
+ }
197
+
198
+
199
+
200
+