@@ -141,6 +141,60 @@ int secp256k1_silentpayments_send_create_shared_secret(const secp256k1_context *
141
141
return 1 ;
142
142
}
143
143
144
+ int secp256k1_silentpayments_create_public_tweak_data (const secp256k1_context * ctx , unsigned char * tweak_data33 , const secp256k1_pubkey * plain_pubkeys , size_t n_plain_pubkeys , const secp256k1_xonly_pubkey * xonly_pubkeys , size_t n_xonly_pubkeys , const unsigned char * outpoint_lowest36 ) {
145
+ size_t i ;
146
+ secp256k1_ge A_sum_ge ;
147
+ secp256k1_gej A_sum_gej ;
148
+ secp256k1_scalar input_hash_scalar ;
149
+ size_t ser_size ;
150
+ int ser_ret ;
151
+
152
+ /* Sanity check inputs */
153
+ VERIFY_CHECK (ctx != NULL );
154
+ ARG_CHECK (tweak_data33 != NULL );
155
+ memset (tweak_data33 , 0 , 33 );
156
+ ARG_CHECK (plain_pubkeys == NULL || n_plain_pubkeys >= 1 );
157
+ ARG_CHECK (xonly_pubkeys == NULL || n_xonly_pubkeys >= 1 );
158
+ ARG_CHECK ((plain_pubkeys != NULL ) || (xonly_pubkeys != NULL ));
159
+ ARG_CHECK ((n_plain_pubkeys + n_xonly_pubkeys ) >= 1 );
160
+ ARG_CHECK (outpoint_lowest36 != NULL );
161
+
162
+ /* Compute input public keys sum: A_sum = A_1 + A_2 + ... + A_n */
163
+ secp256k1_gej_set_infinity (& A_sum_gej );
164
+ for (i = 0 ; i < n_plain_pubkeys ; i ++ ) {
165
+ secp256k1_ge addend ;
166
+ secp256k1_pubkey_load (ctx , & addend , & plain_pubkeys [i ]);
167
+ secp256k1_gej_add_ge (& A_sum_gej , & A_sum_gej , & addend );
168
+ }
169
+
170
+ /* X-only public keys have to be converted to regular public keys (assuming even parity) */
171
+ for (i = 0 ; i < n_xonly_pubkeys ; i ++ ) {
172
+ secp256k1_ge addend ;
173
+ secp256k1_xonly_pubkey_load (ctx , & addend , & xonly_pubkeys [i ]);
174
+ if (secp256k1_fe_is_odd (& addend .y )) {
175
+ secp256k1_fe_negate (& addend .y , & addend .y , 1 );
176
+ }
177
+ VERIFY_CHECK (!secp256k1_fe_is_odd (& addend .y ));
178
+ secp256k1_gej_add_ge (& A_sum_gej , & A_sum_gej , & addend );
179
+ }
180
+ secp256k1_ge_set_gej (& A_sum_ge , & A_sum_gej );
181
+
182
+ /* Compute input_hash = hash(outpoint_L || A_sum) */
183
+ secp256k1_silentpayments_calculate_input_hash (& input_hash_scalar , outpoint_lowest36 , & A_sum_ge );
184
+
185
+ /* Compute A_tweaked = A_sum * input_hash */
186
+ if (!secp256k1_eckey_pubkey_tweak_mul (& A_sum_ge , & input_hash_scalar )) {
187
+ return 0 ;
188
+ }
189
+
190
+ /* Serialize tweak_data */
191
+ ser_ret = secp256k1_eckey_pubkey_serialize (& A_sum_ge , tweak_data33 , & ser_size , 1 );
192
+ VERIFY_CHECK (ser_ret && ser_size == 33 );
193
+ (void )ser_ret ;
194
+
195
+ return 1 ;
196
+ }
197
+
144
198
/* TODO: implement functions for receiver side. */
145
199
146
200
#endif
0 commit comments