1use crate::easycodec::*;
8use crate::sim_context::*;
9
10const CONTRACT_METHOD_GET_PAILLIER_OPERATION_RESULT: &str = "GetPaillierOperationResult";
11const CONTRACT_METHOD_GET_PAILLIER_OPERATION_RESULT_LEN: &str = "GetPaillierOperationResultLen";
12const PAILLIER_OPERATION_TYPE_ADD_CIPHERTEXT: &str = "AddCiphertext";
13const PAILLIER_OPERATION_TYPE_ADD_PLAINTEXT: &str = "AddPlaintext";
14const PAILLIER_OPERATION_TYPE_SUB_CIPHERTEXT: &str = "SubCiphertext";
15const PAILLIER_OPERATION_TYPE_SUB_PLAINTEXT: &str = "SubPlaintext";
16const PAILLIER_OPERATION_TYPE_NUM_MUL: &str = "NumMul";
17
18pub trait PaillierSimContext {
19 fn add_ciphertext(
21 &self,
22 pubkey: Vec<u8>,
23 ciphertext1: Vec<u8>,
24 ciphertext2: Vec<u8>,
25 ) -> Result<Vec<u8>, result_code>;
26 fn add_plaintext(
27 &self,
28 pubkey: Vec<u8>,
29 ciphertext: Vec<u8>,
30 plaintext: &str,
31 ) -> Result<Vec<u8>, result_code>;
32 fn sub_ciphertext(
33 &self,
34 pubkey: Vec<u8>,
35 ciphertext1: Vec<u8>,
36 ciphertext2: Vec<u8>,
37 ) -> Result<Vec<u8>, result_code>;
38 fn sub_plaintext(
39 &self,
40 pubkey: Vec<u8>,
41 ciphertext: Vec<u8>,
42 plaintext: &str,
43 ) -> Result<Vec<u8>, result_code>;
44 fn num_mul(
45 &self,
46 pubkey: Vec<u8>,
47 ciphertext: Vec<u8>,
48 plaintext: &str,
49 ) -> Result<Vec<u8>, result_code>;
50}
51
52pub struct PaillierSimContextImpl {
53 pub common: CommonUtils,
54}
55
56impl PaillierSimContextImpl {
57 pub fn new(ctx_ptr: i32) -> PaillierSimContextImpl {
58 PaillierSimContextImpl {
59 common: CommonUtils { ctx_ptr },
60 }
61 }
62}
63
64impl PaillierSimContext for PaillierSimContextImpl {
65 fn add_ciphertext(
66 &self,
67 pubkey: Vec<u8>,
68 ciphertext1: Vec<u8>,
69 ciphertext2: Vec<u8>,
70 ) -> Result<Vec<u8>, result_code> {
71 paillier_operation(
72 self,
73 pubkey,
74 ciphertext1,
75 ciphertext2,
76 PAILLIER_OPERATION_TYPE_ADD_CIPHERTEXT,
77 )
78 }
79
80 fn add_plaintext(
81 &self,
82 pubkey: Vec<u8>,
83 ciphertext: Vec<u8>,
84 plaintext: &str,
85 ) -> Result<Vec<u8>, result_code> {
86 paillier_operation(
87 self,
88 pubkey,
89 ciphertext,
90 plaintext.to_string().into_bytes(),
91 PAILLIER_OPERATION_TYPE_ADD_PLAINTEXT,
92 )
93 }
94
95 fn sub_ciphertext(
96 &self,
97 pubkey: Vec<u8>,
98 ciphertext1: Vec<u8>,
99 ciphertext2: Vec<u8>,
100 ) -> Result<Vec<u8>, result_code> {
101 paillier_operation(
102 self,
103 pubkey,
104 ciphertext1,
105 ciphertext2,
106 PAILLIER_OPERATION_TYPE_SUB_CIPHERTEXT,
107 )
108 }
109
110 fn sub_plaintext(
111 &self,
112 pubkey: Vec<u8>,
113 ciphertext: Vec<u8>,
114 plaintext: &str,
115 ) -> Result<Vec<u8>, result_code> {
116 paillier_operation(
117 self,
118 pubkey,
119 ciphertext,
120 plaintext.to_string().into_bytes(),
121 PAILLIER_OPERATION_TYPE_SUB_PLAINTEXT,
122 )
123 }
124
125 fn num_mul(
126 &self,
127 pubkey: Vec<u8>,
128 ciphertext: Vec<u8>,
129 plaintext: &str,
130 ) -> Result<Vec<u8>, result_code> {
131 paillier_operation(
132 self,
133 pubkey,
134 ciphertext,
135 plaintext.to_string().into_bytes(),
136 PAILLIER_OPERATION_TYPE_NUM_MUL,
137 )
138 }
139}
140
141fn paillier_operation(
142 crypto_sim_context: &PaillierSimContextImpl,
143 pubkey: Vec<u8>,
144 operate_one: Vec<u8>,
145 operate_two: Vec<u8>,
146 operation_type: &str,
147) -> Result<Vec<u8>, result_code> {
148 let ec = &mut EasyCodec::new();
149 ec.add_bytes("pubKey", pubkey);
150 ec.add_bytes("operandOne", operate_one);
151 ec.add_bytes("operandTwo", operate_two);
152 ec.add_string("opType", operation_type);
153 crypto_sim_context.common.get_bytes_from_chain(
154 ec,
155 CONTRACT_METHOD_GET_PAILLIER_OPERATION_RESULT_LEN,
156 CONTRACT_METHOD_GET_PAILLIER_OPERATION_RESULT,
157 )
158}