confium 0.7.1 → 0.7.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -1
- data/Cargo.lock +218 -512
- data/ext/confium_native/Cargo.toml +9 -12
- data/ext/confium_native/src/lib.rs +1 -0
- data/ext/confium_native/src/tc.rs +1 -0
- data/ext/confium_native/src/tc_mta.rs +378 -0
- data/lib/confium/version.rb +1 -1
- metadata +2 -1
|
@@ -42,27 +42,24 @@ confium-attributes = "0.3.1"
|
|
|
42
42
|
confium-pki = "0.5.6"
|
|
43
43
|
confium-store = "0.5.8"
|
|
44
44
|
confium-deployment = "0.3"
|
|
45
|
-
confium-tc = "0.
|
|
45
|
+
confium-tc = "0.9"
|
|
46
46
|
confium-tc-frost-p256 = "0.4"
|
|
47
47
|
confium-tc-elgamal-p256 = "0.4"
|
|
48
|
-
confium-tc-cmp20 = "0.
|
|
49
|
-
confium-tc-gg18 = "0.
|
|
48
|
+
confium-tc-cmp20 = "0.9"
|
|
49
|
+
confium-tc-gg18 = "0.9"
|
|
50
50
|
|
|
51
51
|
# Per-party session protocol: the tc-core 0.4 registry line. The 0.3-era
|
|
52
52
|
# in-process drivers above keep their own registry harmlessly.
|
|
53
|
-
confium-tc-session = { package = "confium-tc-core", version = "0.
|
|
54
|
-
confium-tc-frost-ed25519 = "0.
|
|
55
|
-
|
|
56
|
-
# Newly published shared crypto crates (confium product restructuring).
|
|
57
|
-
confium-tc-core = "0.3"
|
|
58
|
-
confium-crypto-vss = "0.3"
|
|
59
|
-
confium-crypto-zk = "0.3"
|
|
60
|
-
confium-privacy = "0.3"
|
|
61
|
-
confium-observability = "0.3"
|
|
53
|
+
confium-tc-session = { package = "confium-tc-core", version = "0.9" }
|
|
54
|
+
confium-tc-frost-ed25519 = "0.9"
|
|
62
55
|
|
|
63
56
|
# P-256 scalar/point types used by the TC surface.
|
|
64
57
|
p256 = { version = "0.13", features = ["ecdsa"] }
|
|
65
58
|
|
|
59
|
+
# Hex integer codecs for the MtA surface.
|
|
60
|
+
num-bigint = "0.4"
|
|
61
|
+
num-traits = "0.2"
|
|
62
|
+
|
|
66
63
|
ed25519-dalek = { version = "2", features = ["rand_core"] }
|
|
67
64
|
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }
|
|
68
65
|
|
|
@@ -232,6 +232,7 @@ pub fn init(ruby: &Ruby, parent: magnus::RModule) -> Result<(), Error> {
|
|
|
232
232
|
let cmp20 = tc.define_module("Cmp20")?;
|
|
233
233
|
cmp20.define_module_function("keygen", function!(cmp20_keygen, 2))?;
|
|
234
234
|
cmp20.define_module_function("sign", function!(cmp20_sign, 3))?;
|
|
235
|
+
crate::tc_mta::init(ruby, &cmp20)?;
|
|
235
236
|
|
|
236
237
|
let gg18 = tc.define_module("Gg18")?;
|
|
237
238
|
gg18.define_module_function("keygen", function!(gg18_keygen, 2))?;
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
//! Confium::TC::Cmp20::Mta — the proved MtA sub-protocol binding.
|
|
2
|
+
//!
|
|
3
|
+
//! Wraps `confium-tc-cmp20`'s `paillier_mta`: the GG18/GG20 §3 +
|
|
4
|
+
//! Appendix A multiplicative-to-additive conversion with zero-knowledge
|
|
5
|
+
//! range proofs on every ciphertext. `full` runs the whole exchange
|
|
6
|
+
//! in-process; `party_i_init` / `party_j_respond` / `party_i_finish`
|
|
7
|
+
//! expose the three passes with messages as plain Hashes of hex
|
|
8
|
+
//! integers so rounds can be JSON-encoded onto a transport.
|
|
9
|
+
//!
|
|
10
|
+
//! Trust model: coordinator. The finish step decrypts the response
|
|
11
|
+
//! under the RESPONDER's Paillier key — that is the shape the upstream
|
|
12
|
+
//! crate implements — so the process calling `party_i_finish` (or
|
|
13
|
+
//! `full`) must hold the keypair, exactly like the in-process signing
|
|
14
|
+
//! drivers. Splitting the passes across machines needs the upstream
|
|
15
|
+
//! per-party state machine; until it exists, these are message-level
|
|
16
|
+
//! building blocks under a trusted coordinator.
|
|
17
|
+
|
|
18
|
+
use confium_tc::paillier::{
|
|
19
|
+
generate_keypair as generate_paillier_keypair, PaillierKeypair, PaillierPrivateKey,
|
|
20
|
+
PaillierPublicKey,
|
|
21
|
+
};
|
|
22
|
+
use confium_tc_cmp20::mta_proofs::{
|
|
23
|
+
generate_commitment_key, p256_order, CommitmentKey, RangeProof, RespondentProof,
|
|
24
|
+
};
|
|
25
|
+
use confium_tc_cmp20::paillier_mta::{
|
|
26
|
+
full_mta_proved, party_i_finish_proved, party_i_init_proved, party_j_respond_proved,
|
|
27
|
+
MtaProofError, ProvedMessage1, ProvedMessage2,
|
|
28
|
+
};
|
|
29
|
+
use magnus::prelude::*;
|
|
30
|
+
use magnus::{Error, RHash, RString, Ruby, TryConvert};
|
|
31
|
+
use num_bigint::BigUint;
|
|
32
|
+
use num_traits::Num;
|
|
33
|
+
|
|
34
|
+
const ALGORITHM: &str = "CMP20-ECDSA-P256";
|
|
35
|
+
|
|
36
|
+
fn parse_hex(value: &str, what: &str) -> Result<BigUint, Error> {
|
|
37
|
+
BigUint::from_str_radix(value.trim(), 16)
|
|
38
|
+
.map_err(|_| crate::util::arg_error(format!("{what} must be a hex integer")))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fn hex_string(ruby: &Ruby, value: &BigUint) -> RString {
|
|
42
|
+
ruby.str_from_slice(value.to_str_radix(16).as_bytes())
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn string_field(hash: &RHash, key: &str) -> Result<String, Error> {
|
|
46
|
+
let value: magnus::Value = hash
|
|
47
|
+
.get(key)
|
|
48
|
+
.ok_or_else(|| crate::util::arg_error(format!("missing field {key:?}")))?;
|
|
49
|
+
String::try_convert(value)
|
|
50
|
+
.map_err(|_| crate::util::arg_error(format!("field {key:?} must be a String")))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fn hash_field(hash: &RHash, key: &str) -> Result<RHash, Error> {
|
|
54
|
+
let value: magnus::Value = hash
|
|
55
|
+
.get(key)
|
|
56
|
+
.ok_or_else(|| crate::util::arg_error(format!("missing field {key:?}")))?;
|
|
57
|
+
RHash::try_convert(value)
|
|
58
|
+
.map_err(|_| crate::util::arg_error(format!("field {key:?} must be a Hash")))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fn set_hex(ruby: &Ruby, hash: &RHash, key: &str, value: &BigUint) -> Result<(), Error> {
|
|
62
|
+
hash.aset(key, hex_string(ruby, value))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fn check_prime_bits(prime_bits: i64) -> Result<u32, Error> {
|
|
66
|
+
if !(64..=8192).contains(&prime_bits) {
|
|
67
|
+
return Err(crate::util::arg_error(format!(
|
|
68
|
+
"prime_bits must be between 64 and 8192, got {prime_bits}"
|
|
69
|
+
)));
|
|
70
|
+
}
|
|
71
|
+
Ok(prime_bits as u32)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---- key codecs ---------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
fn public_from_hash(hash: &RHash) -> Result<PaillierPublicKey, Error> {
|
|
77
|
+
Ok(PaillierPublicKey {
|
|
78
|
+
n: parse_hex(&string_field(hash, "n")?, "public key n")?,
|
|
79
|
+
n_squared: parse_hex(&string_field(hash, "n_squared")?, "public key n_squared")?,
|
|
80
|
+
g: parse_hex(&string_field(hash, "g")?, "public key g")?,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fn private_from_hash(hash: &RHash) -> Result<PaillierPrivateKey, Error> {
|
|
85
|
+
Ok(PaillierPrivateKey {
|
|
86
|
+
lambda: parse_hex(&string_field(hash, "lambda")?, "private key lambda")?,
|
|
87
|
+
mu: parse_hex(&string_field(hash, "mu")?, "private key mu")?,
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fn public_to_hash(ruby: &Ruby, public: &PaillierPublicKey) -> Result<RHash, Error> {
|
|
92
|
+
let out = ruby.hash_new();
|
|
93
|
+
set_hex(ruby, &out, "n", &public.n)?;
|
|
94
|
+
set_hex(ruby, &out, "n_squared", &public.n_squared)?;
|
|
95
|
+
set_hex(ruby, &out, "g", &public.g)?;
|
|
96
|
+
Ok(out)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fn keypair_to_hash(ruby: &Ruby, kp: &PaillierKeypair) -> Result<RHash, Error> {
|
|
100
|
+
let out = ruby.hash_new();
|
|
101
|
+
out.aset("public", public_to_hash(ruby, &kp.public)?)?;
|
|
102
|
+
let private = ruby.hash_new();
|
|
103
|
+
set_hex(ruby, &private, "lambda", &kp.private.lambda)?;
|
|
104
|
+
set_hex(ruby, &private, "mu", &kp.private.mu)?;
|
|
105
|
+
out.aset("private", private)?;
|
|
106
|
+
Ok(out)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fn commitment_key_from_hash(hash: &RHash) -> Result<CommitmentKey, Error> {
|
|
110
|
+
Ok(CommitmentKey {
|
|
111
|
+
n_tilde: parse_hex(&string_field(hash, "n_tilde")?, "commitment key n_tilde")?,
|
|
112
|
+
h1: parse_hex(&string_field(hash, "h1")?, "commitment key h1")?,
|
|
113
|
+
h2: parse_hex(&string_field(hash, "h2")?, "commitment key h2")?,
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fn commitment_key_to_hash(ruby: &Ruby, ck: &CommitmentKey) -> Result<RHash, Error> {
|
|
118
|
+
let out = ruby.hash_new();
|
|
119
|
+
set_hex(ruby, &out, "n_tilde", &ck.n_tilde)?;
|
|
120
|
+
set_hex(ruby, &out, "h1", &ck.h1)?;
|
|
121
|
+
set_hex(ruby, &out, "h2", &ck.h2)?;
|
|
122
|
+
Ok(out)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ---- message codecs -----------------------------------------------------
|
|
126
|
+
|
|
127
|
+
fn range_proof_from_hash(hash: &RHash) -> Result<RangeProof, Error> {
|
|
128
|
+
Ok(RangeProof {
|
|
129
|
+
z: parse_hex(&string_field(hash, "z")?, "range proof z")?,
|
|
130
|
+
u: parse_hex(&string_field(hash, "u")?, "range proof u")?,
|
|
131
|
+
w: parse_hex(&string_field(hash, "w")?, "range proof w")?,
|
|
132
|
+
s: parse_hex(&string_field(hash, "s")?, "range proof s")?,
|
|
133
|
+
s1: parse_hex(&string_field(hash, "s1")?, "range proof s1")?,
|
|
134
|
+
s2: parse_hex(&string_field(hash, "s2")?, "range proof s2")?,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fn range_proof_to_hash(ruby: &Ruby, proof: &RangeProof) -> Result<RHash, Error> {
|
|
139
|
+
let out = ruby.hash_new();
|
|
140
|
+
set_hex(ruby, &out, "z", &proof.z)?;
|
|
141
|
+
set_hex(ruby, &out, "u", &proof.u)?;
|
|
142
|
+
set_hex(ruby, &out, "w", &proof.w)?;
|
|
143
|
+
set_hex(ruby, &out, "s", &proof.s)?;
|
|
144
|
+
set_hex(ruby, &out, "s1", &proof.s1)?;
|
|
145
|
+
set_hex(ruby, &out, "s2", &proof.s2)?;
|
|
146
|
+
Ok(out)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
fn respondent_proof_from_hash(hash: &RHash) -> Result<RespondentProof, Error> {
|
|
150
|
+
Ok(RespondentProof {
|
|
151
|
+
z: parse_hex(&string_field(hash, "z")?, "respondent proof z")?,
|
|
152
|
+
z_prime: parse_hex(&string_field(hash, "z_prime")?, "respondent proof z_prime")?,
|
|
153
|
+
t: parse_hex(&string_field(hash, "t")?, "respondent proof t")?,
|
|
154
|
+
v: parse_hex(&string_field(hash, "v")?, "respondent proof v")?,
|
|
155
|
+
w: parse_hex(&string_field(hash, "w")?, "respondent proof w")?,
|
|
156
|
+
s: parse_hex(&string_field(hash, "s")?, "respondent proof s")?,
|
|
157
|
+
s1: parse_hex(&string_field(hash, "s1")?, "respondent proof s1")?,
|
|
158
|
+
s2: parse_hex(&string_field(hash, "s2")?, "respondent proof s2")?,
|
|
159
|
+
t1: parse_hex(&string_field(hash, "t1")?, "respondent proof t1")?,
|
|
160
|
+
t2: parse_hex(&string_field(hash, "t2")?, "respondent proof t2")?,
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fn respondent_proof_to_hash(ruby: &Ruby, proof: &RespondentProof) -> Result<RHash, Error> {
|
|
165
|
+
let out = ruby.hash_new();
|
|
166
|
+
set_hex(ruby, &out, "z", &proof.z)?;
|
|
167
|
+
set_hex(ruby, &out, "z_prime", &proof.z_prime)?;
|
|
168
|
+
set_hex(ruby, &out, "t", &proof.t)?;
|
|
169
|
+
set_hex(ruby, &out, "v", &proof.v)?;
|
|
170
|
+
set_hex(ruby, &out, "w", &proof.w)?;
|
|
171
|
+
set_hex(ruby, &out, "s", &proof.s)?;
|
|
172
|
+
set_hex(ruby, &out, "s1", &proof.s1)?;
|
|
173
|
+
set_hex(ruby, &out, "s2", &proof.s2)?;
|
|
174
|
+
set_hex(ruby, &out, "t1", &proof.t1)?;
|
|
175
|
+
set_hex(ruby, &out, "t2", &proof.t2)?;
|
|
176
|
+
Ok(out)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fn msg1_from_hash(hash: &RHash) -> Result<ProvedMessage1, Error> {
|
|
180
|
+
Ok(ProvedMessage1 {
|
|
181
|
+
ciphertext: parse_hex(&string_field(hash, "ciphertext")?, "message 1 ciphertext")?,
|
|
182
|
+
range_proof: range_proof_from_hash(&hash_field(hash, "range_proof")?)?,
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
fn msg1_to_hash(ruby: &Ruby, msg: &ProvedMessage1) -> Result<RHash, Error> {
|
|
187
|
+
let out = ruby.hash_new();
|
|
188
|
+
set_hex(ruby, &out, "ciphertext", &msg.ciphertext)?;
|
|
189
|
+
out.aset("range_proof", range_proof_to_hash(ruby, &msg.range_proof)?)?;
|
|
190
|
+
Ok(out)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
fn msg2_from_hash(hash: &RHash) -> Result<ProvedMessage2, Error> {
|
|
194
|
+
Ok(ProvedMessage2 {
|
|
195
|
+
ciphertext: parse_hex(&string_field(hash, "ciphertext")?, "message 2 ciphertext")?,
|
|
196
|
+
respondent_proof: respondent_proof_from_hash(&hash_field(hash, "respondent_proof")?)?,
|
|
197
|
+
beta: parse_hex(&string_field(hash, "beta")?, "message 2 beta")?,
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
fn msg2_to_hash(ruby: &Ruby, msg: &ProvedMessage2) -> Result<RHash, Error> {
|
|
202
|
+
let out = ruby.hash_new();
|
|
203
|
+
set_hex(ruby, &out, "ciphertext", &msg.ciphertext)?;
|
|
204
|
+
out.aset(
|
|
205
|
+
"respondent_proof",
|
|
206
|
+
respondent_proof_to_hash(ruby, &msg.respondent_proof)?,
|
|
207
|
+
)?;
|
|
208
|
+
set_hex(ruby, &out, "beta", &msg.beta)?;
|
|
209
|
+
Ok(out)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ---- ops ----------------------------------------------------------------
|
|
213
|
+
|
|
214
|
+
fn mta_error(ruby: &Ruby, operation: &str, e: MtaProofError) -> Error {
|
|
215
|
+
let message = e.to_string();
|
|
216
|
+
crate::audit::fire_event(
|
|
217
|
+
operation,
|
|
218
|
+
"failure",
|
|
219
|
+
Some(ALGORITHM),
|
|
220
|
+
None,
|
|
221
|
+
Some(&message),
|
|
222
|
+
);
|
|
223
|
+
Error::new(mta_error_class(ruby), message)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fn mta_generate_keypair(ruby: &Ruby, prime_bits: i64) -> Result<RHash, Error> {
|
|
227
|
+
let bits = check_prime_bits(prime_bits)?;
|
|
228
|
+
// Safe-prime search is CPU-bound and takes seconds at production
|
|
229
|
+
// sizes — release the GVL so sibling Ruby threads keep running.
|
|
230
|
+
let kp = unsafe { crate::gvl::without_gvl(|| generate_paillier_keypair(bits)) };
|
|
231
|
+
crate::audit::fire_event("tc_cmp20_mta_keypair", "success", Some(ALGORITHM), None, None);
|
|
232
|
+
keypair_to_hash(ruby, &kp)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
fn mta_generate_commitment_key(ruby: &Ruby, prime_bits: i64) -> Result<RHash, Error> {
|
|
236
|
+
let bits = check_prime_bits(prime_bits)?;
|
|
237
|
+
let ck = unsafe { crate::gvl::without_gvl(|| generate_commitment_key(bits)) };
|
|
238
|
+
crate::audit::fire_event("tc_cmp20_mta_commitment_key", "success", Some(ALGORITHM), None, None);
|
|
239
|
+
commitment_key_to_hash(ruby, &ck)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
fn mta_party_i_init(
|
|
243
|
+
ruby: &Ruby,
|
|
244
|
+
j_public: RHash,
|
|
245
|
+
ck_j: RHash,
|
|
246
|
+
q: String,
|
|
247
|
+
k_i: String,
|
|
248
|
+
) -> Result<RHash, Error> {
|
|
249
|
+
let public = public_from_hash(&j_public)?;
|
|
250
|
+
let ck = commitment_key_from_hash(&ck_j)?;
|
|
251
|
+
let q = parse_hex(&q, "q")?;
|
|
252
|
+
let k_i = parse_hex(&k_i, "k_i")?;
|
|
253
|
+
let msg = party_i_init_proved(&public, &ck, &q, &k_i).map_err(|e| mta_error(ruby, "tc_cmp20_mta_init", e))?;
|
|
254
|
+
crate::audit::fire_event("tc_cmp20_mta_init", "success", Some(ALGORITHM), None, None);
|
|
255
|
+
msg1_to_hash(ruby, &msg)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
fn mta_party_j_respond(
|
|
259
|
+
ruby: &Ruby,
|
|
260
|
+
j_public: RHash,
|
|
261
|
+
j_private: RHash,
|
|
262
|
+
ck_i: RHash,
|
|
263
|
+
ck_j: RHash,
|
|
264
|
+
q: String,
|
|
265
|
+
msg1: RHash,
|
|
266
|
+
x_j: String,
|
|
267
|
+
) -> Result<magnus::RArray, Error> {
|
|
268
|
+
let public = public_from_hash(&j_public)?;
|
|
269
|
+
let private = private_from_hash(&j_private)?;
|
|
270
|
+
let ck_i = commitment_key_from_hash(&ck_i)?;
|
|
271
|
+
let ck_j = commitment_key_from_hash(&ck_j)?;
|
|
272
|
+
let q = parse_hex(&q, "q")?;
|
|
273
|
+
let msg1 = msg1_from_hash(&msg1)?;
|
|
274
|
+
let x_j = parse_hex(&x_j, "x_j")?;
|
|
275
|
+
let (msg2, beta) = party_j_respond_proved(
|
|
276
|
+
&PaillierKeypair {
|
|
277
|
+
public,
|
|
278
|
+
private,
|
|
279
|
+
},
|
|
280
|
+
&ck_i,
|
|
281
|
+
&ck_j,
|
|
282
|
+
&q,
|
|
283
|
+
&msg1,
|
|
284
|
+
&x_j,
|
|
285
|
+
)
|
|
286
|
+
.map_err(|e| mta_error(ruby, "tc_cmp20_mta_respond", e))?;
|
|
287
|
+
crate::audit::fire_event("tc_cmp20_mta_respond", "success", Some(ALGORITHM), None, None);
|
|
288
|
+
let out = ruby.ary_new_capa(2);
|
|
289
|
+
out.push(msg2_to_hash(ruby, &msg2)?)?;
|
|
290
|
+
out.push(hex_string(ruby, &beta))?;
|
|
291
|
+
Ok(out)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
fn mta_party_i_finish(
|
|
295
|
+
ruby: &Ruby,
|
|
296
|
+
j_public: RHash,
|
|
297
|
+
j_private: RHash,
|
|
298
|
+
ck_i: RHash,
|
|
299
|
+
q: String,
|
|
300
|
+
msg1_ciphertext: String,
|
|
301
|
+
msg2: RHash,
|
|
302
|
+
) -> Result<RString, Error> {
|
|
303
|
+
let public = public_from_hash(&j_public)?;
|
|
304
|
+
let private = private_from_hash(&j_private)?;
|
|
305
|
+
let ck_i = commitment_key_from_hash(&ck_i)?;
|
|
306
|
+
let q = parse_hex(&q, "q")?;
|
|
307
|
+
let ciphertext = parse_hex(&msg1_ciphertext, "message 1 ciphertext")?;
|
|
308
|
+
let msg2 = msg2_from_hash(&msg2)?;
|
|
309
|
+
let alpha = party_i_finish_proved(&public, &ck_i, &q, &ciphertext, &private, &msg2)
|
|
310
|
+
.map_err(|e| mta_error(ruby, "tc_cmp20_mta_finish", e))?;
|
|
311
|
+
crate::audit::fire_event("tc_cmp20_mta_finish", "success", Some(ALGORITHM), None, None);
|
|
312
|
+
Ok(hex_string(ruby, &alpha))
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
fn mta_full(
|
|
316
|
+
ruby: &Ruby,
|
|
317
|
+
j_public: RHash,
|
|
318
|
+
j_private: RHash,
|
|
319
|
+
ck_i: RHash,
|
|
320
|
+
ck_j: RHash,
|
|
321
|
+
q: String,
|
|
322
|
+
k_i: String,
|
|
323
|
+
x_j: String,
|
|
324
|
+
) -> Result<magnus::RArray, Error> {
|
|
325
|
+
let public = public_from_hash(&j_public)?;
|
|
326
|
+
let private = private_from_hash(&j_private)?;
|
|
327
|
+
let ck_i = commitment_key_from_hash(&ck_i)?;
|
|
328
|
+
let ck_j = commitment_key_from_hash(&ck_j)?;
|
|
329
|
+
let q = parse_hex(&q, "q")?;
|
|
330
|
+
let k_i = parse_hex(&k_i, "k_i")?;
|
|
331
|
+
let x_j = parse_hex(&x_j, "x_j")?;
|
|
332
|
+
let (alpha, beta) = full_mta_proved(
|
|
333
|
+
&PaillierKeypair {
|
|
334
|
+
public,
|
|
335
|
+
private,
|
|
336
|
+
},
|
|
337
|
+
&ck_i,
|
|
338
|
+
&ck_j,
|
|
339
|
+
&q,
|
|
340
|
+
&k_i,
|
|
341
|
+
&x_j,
|
|
342
|
+
)
|
|
343
|
+
.map_err(|e| mta_error(ruby, "tc_cmp20_mta_full", e))?;
|
|
344
|
+
crate::audit::fire_event("tc_cmp20_mta_full", "success", Some(ALGORITHM), None, None);
|
|
345
|
+
let out = ruby.ary_new_capa(2);
|
|
346
|
+
out.push(hex_string(ruby, &alpha))?;
|
|
347
|
+
out.push(hex_string(ruby, &beta))?;
|
|
348
|
+
Ok(out)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
pub fn init(ruby: &Ruby, cmp20: &magnus::RModule) -> Result<(), Error> {
|
|
352
|
+
let mta = cmp20.define_module("Mta")?;
|
|
353
|
+
let error = cmp20.define_error("MtaError", ruby.exception_standard_error())?;
|
|
354
|
+
cmp20.const_set("MTA_ERROR", error)?;
|
|
355
|
+
let order = p256_order().to_str_radix(16);
|
|
356
|
+
mta.const_set("P256_ORDER", ruby.str_from_slice(order.as_bytes()))?;
|
|
357
|
+
|
|
358
|
+
mta.define_module_function("generate_keypair", magnus::function!(mta_generate_keypair, 1))?;
|
|
359
|
+
mta.define_module_function(
|
|
360
|
+
"generate_commitment_key",
|
|
361
|
+
magnus::function!(mta_generate_commitment_key, 1),
|
|
362
|
+
)?;
|
|
363
|
+
mta.define_module_function("party_i_init", magnus::function!(mta_party_i_init, 4))?;
|
|
364
|
+
mta.define_module_function("party_j_respond", magnus::function!(mta_party_j_respond, 7))?;
|
|
365
|
+
mta.define_module_function("party_i_finish", magnus::function!(mta_party_i_finish, 6))?;
|
|
366
|
+
mta.define_module_function("full", magnus::function!(mta_full, 7))?;
|
|
367
|
+
Ok(())
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
fn mta_error_class(ruby: &Ruby) -> magnus::ExceptionClass {
|
|
371
|
+
ruby
|
|
372
|
+
.class_object()
|
|
373
|
+
.const_get::<_, magnus::RModule>("Confium")
|
|
374
|
+
.and_then(|m| m.const_get::<_, magnus::RModule>("TC"))
|
|
375
|
+
.and_then(|m| m.const_get::<_, magnus::RModule>("Cmp20"))
|
|
376
|
+
.and_then(|m| m.const_get::<_, magnus::ExceptionClass>("MTA_ERROR"))
|
|
377
|
+
.unwrap_or_else(|_| ruby.exception_runtime_error())
|
|
378
|
+
}
|
data/lib/confium/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: confium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Open
|
|
@@ -129,6 +129,7 @@ files:
|
|
|
129
129
|
- ext/confium_native/src/pki.rs
|
|
130
130
|
- ext/confium_native/src/store.rs
|
|
131
131
|
- ext/confium_native/src/tc.rs
|
|
132
|
+
- ext/confium_native/src/tc_mta.rs
|
|
132
133
|
- ext/confium_native/src/tc_session.rs
|
|
133
134
|
- ext/confium_native/src/transparency.rs
|
|
134
135
|
- ext/confium_native/src/util.rs
|