• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 22632786303

03 Mar 2026 04:33PM UTC coverage: 90.222% (-0.1%) from 90.317%
22632786303

Pull #5404

github

web-flow
Merge 29e610b86 into a78272b61
Pull Request #5404: Add EC scalars and points to FFI

103594 of 114821 relevant lines covered (90.22%)

11540883.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.61
/src/lib/ffi/ffi_ec.cpp
1
/*
2
* (C) 2025 Jack Lloyd
3
* (C) 2025,2026 Dominik Schricker
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/ffi.h>
9

10
#include <botan/internal/ffi_ec.h>
11
#include <botan/internal/ffi_mp.h>
12
#include <botan/internal/ffi_oid.h>
13
#include <botan/internal/ffi_rng.h>
14
#include <botan/internal/ffi_util.h>
15
#include <functional>
16

17
extern "C" {
18

19
using namespace Botan_FFI;
20

21
int botan_ec_group_destroy(botan_ec_group_t ec_group) {
13✔
22
   return BOTAN_FFI_CHECKED_DELETE(ec_group);
13✔
23
}
24

25
int botan_ec_group_supports_application_specific_group(int* out) {
3✔
26
   if(out == nullptr) {
3✔
27
      return BOTAN_FFI_ERROR_NULL_POINTER;
28
   }
29
   if(Botan::EC_Group::supports_application_specific_group()) {
3✔
30
      *out = 1;
3✔
31
   } else {
32
      *out = 0;
×
33
   }
34
   return BOTAN_FFI_SUCCESS;
35
}
36

37
int botan_ec_group_supports_named_group(const char* name, int* out) {
7✔
38
   return ffi_guard_thunk(__func__, [=]() -> int {
7✔
39
      if(name == nullptr || out == nullptr) {
7✔
40
         return BOTAN_FFI_ERROR_NULL_POINTER;
41
      }
42
      if(Botan::EC_Group::supports_named_group(name)) {
7✔
43
         *out = 1;
7✔
44
      } else {
45
         *out = 0;
×
46
      }
47
      return BOTAN_FFI_SUCCESS;
48
   });
7✔
49
}
50

51
int botan_ec_group_from_params(botan_ec_group_t* ec_group,
2✔
52
                               botan_asn1_oid_t oid,
53
                               botan_mp_t p,
54
                               botan_mp_t a,
55
                               botan_mp_t b,
56
                               botan_mp_t base_x,
57
                               botan_mp_t base_y,
58
                               botan_mp_t order) {
59
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
60
      if(ec_group == nullptr) {
2✔
61
         return BOTAN_FFI_ERROR_NULL_POINTER;
62
      }
63

64
      Botan::EC_Group group(
2✔
65
         safe_get(oid), safe_get(p), safe_get(a), safe_get(b), safe_get(base_x), safe_get(base_y), safe_get(order));
2✔
66

67
      auto group_ptr = std::make_unique<Botan::EC_Group>(std::move(group));
2✔
68
      return ffi_new_object(ec_group, std::move(group_ptr));
2✔
69
   });
2✔
70
}
71

72
int botan_ec_group_from_ber(botan_ec_group_t* ec_group, const uint8_t* ber, size_t ber_len) {
2✔
73
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
74
      if(ec_group == nullptr || ber == nullptr) {
2✔
75
         return BOTAN_FFI_ERROR_NULL_POINTER;
76
      }
77

78
      Botan::EC_Group group(ber, ber_len);
2✔
79

80
      auto group_ptr = std::make_unique<Botan::EC_Group>(std::move(group));
2✔
81
      return ffi_new_object(ec_group, std::move(group_ptr));
2✔
82
   });
2✔
83
}
84

85
int botan_ec_group_from_pem(botan_ec_group_t* ec_group, const char* pem) {
3✔
86
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
87
      if(ec_group == nullptr || pem == nullptr) {
3✔
88
         return BOTAN_FFI_ERROR_NULL_POINTER;
89
      }
90

91
      Botan::EC_Group group = Botan::EC_Group::from_PEM(pem);
3✔
92

93
      auto group_ptr = std::make_unique<Botan::EC_Group>(std::move(group));
3✔
94
      return ffi_new_object(ec_group, std::move(group_ptr));
3✔
95
   });
3✔
96
}
97

98
int botan_ec_group_from_oid(botan_ec_group_t* ec_group, botan_asn1_oid_t oid) {
3✔
99
   return ffi_guard_thunk(__func__, [=]() -> int {
3✔
100
      if(ec_group == nullptr) {
3✔
101
         return BOTAN_FFI_ERROR_NULL_POINTER;
102
      }
103

104
      Botan::EC_Group group = Botan::EC_Group::from_OID(safe_get(oid));
3✔
105

106
      auto group_ptr = std::make_unique<Botan::EC_Group>(std::move(group));
2✔
107
      return ffi_new_object(ec_group, std::move(group_ptr));
2✔
108
   });
2✔
109
}
110

111
int botan_ec_group_from_name(botan_ec_group_t* ec_group, const char* name) {
5✔
112
   return ffi_guard_thunk(__func__, [=]() -> int {
5✔
113
      if(ec_group == nullptr || name == nullptr) {
5✔
114
         return BOTAN_FFI_ERROR_NULL_POINTER;
115
      }
116

117
      Botan::EC_Group group = Botan::EC_Group::from_name(name);
5✔
118

119
      auto group_ptr = std::make_unique<Botan::EC_Group>(std::move(group));
4✔
120
      return ffi_new_object(ec_group, std::move(group_ptr));
4✔
121
   });
4✔
122
}
123

124
int botan_ec_group_unregister(botan_asn1_oid_t oid) {
8✔
125
   return BOTAN_FFI_VISIT(oid, [=](const auto& o) -> int { return Botan::EC_Group::unregister(o) ? 1 : 0; });
16✔
126
}
127

128
int botan_ec_group_view_der(botan_ec_group_t ec_group, botan_view_ctx ctx, botan_view_bin_fn view) {
2✔
129
   return BOTAN_FFI_VISIT(ec_group,
8✔
130
                          [=](const auto& g) -> int { return invoke_view_callback(view, ctx, g.DER_encode()); });
131
}
132

133
int botan_ec_group_view_pem(botan_ec_group_t ec_group, botan_view_ctx ctx, botan_view_str_fn view) {
2✔
134
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
6✔
135
      return invoke_view_callback(view, ctx, g.PEM_encode(Botan::EC_Group_Encoding::NamedCurve));
136
   });
137
}
138

139
int botan_ec_group_get_curve_oid(botan_asn1_oid_t* oid, botan_ec_group_t ec_group) {
4✔
140
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
8✔
141
      if(oid == nullptr) {
142
         return BOTAN_FFI_ERROR_NULL_POINTER;
143
      }
144
      auto oid_ptr = std::make_unique<Botan::OID>(g.get_curve_oid());
145
      return ffi_new_object(oid, std::move(oid_ptr));
146
   });
147
}
148

149
namespace {
150
int botan_ec_group_get_component(botan_mp_t* out,
26✔
151
                                 botan_ec_group_t ec_group,
152
                                 const std::function<const Botan::BigInt&(const Botan::EC_Group&)>& getter) {
153
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
104✔
154
      if(out == nullptr) {
155
         return BOTAN_FFI_ERROR_NULL_POINTER;
156
      }
157
      auto val = std::make_unique<Botan::BigInt>(getter(g));
158
      return ffi_new_object(out, std::move(val));
159
   });
160
}
161
}  // namespace
162

163
int botan_ec_group_get_p(botan_mp_t* p, botan_ec_group_t ec_group) {
6✔
164
   return botan_ec_group_get_component(p, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_p(); });
18✔
165
}
166

167
int botan_ec_group_get_a(botan_mp_t* a, botan_ec_group_t ec_group) {
4✔
168
   return botan_ec_group_get_component(a, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_a(); });
12✔
169
}
170

171
int botan_ec_group_get_b(botan_mp_t* b, botan_ec_group_t ec_group) {
4✔
172
   return botan_ec_group_get_component(b, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_b(); });
12✔
173
}
174

175
int botan_ec_group_get_g_x(botan_mp_t* g_x, botan_ec_group_t ec_group) {
4✔
176
   return botan_ec_group_get_component(
4✔
177
      g_x, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_g_x(); });
8✔
178
}
179

180
int botan_ec_group_get_g_y(botan_mp_t* g_y, botan_ec_group_t ec_group) {
4✔
181
   return botan_ec_group_get_component(
4✔
182
      g_y, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_g_y(); });
8✔
183
}
184

185
int botan_ec_group_get_order(botan_mp_t* order, botan_ec_group_t ec_group) {
4✔
186
   return botan_ec_group_get_component(
4✔
187
      order, ec_group, [](const auto& g) -> const Botan::BigInt& { return g.get_order(); });
8✔
188
}
189

190
int botan_ec_group_get_generator(botan_ec_group_t ec_group, botan_ec_point_t* generator) {
×
191
   if(Botan::any_null_pointers(generator)) {
×
192
      return BOTAN_FFI_ERROR_NULL_POINTER;
193
   }
194
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
195
      Botan::EC_AffinePoint pt = Botan::EC_AffinePoint::generator(g);
196
      return ffi_new_object(generator, std::make_unique<Botan::EC_AffinePoint>(std::move(pt)));
197
   });
198
}
199

200
int botan_ec_group_get_identity(botan_ec_group_t ec_group, botan_ec_point_t* identity) {
×
201
   if(Botan::any_null_pointers(identity)) {
×
202
      return BOTAN_FFI_ERROR_NULL_POINTER;
203
   }
204
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
205
      Botan::EC_AffinePoint pt = Botan::EC_AffinePoint::identity(g);
206
      return ffi_new_object(identity, std::make_unique<Botan::EC_AffinePoint>(std::move(pt)));
207
   });
208
}
209

210
int botan_ec_group_equal(botan_ec_group_t curve1_w, botan_ec_group_t curve2_w) {
10✔
211
   return BOTAN_FFI_VISIT(curve1_w, [=](const auto& curve1) -> int { return curve1 == safe_get(curve2_w); });
20✔
212
}
213

214
// ec scalars
215

216
int botan_ec_scalar_destroy(botan_ec_scalar_t ec_scalar) {
×
217
   return BOTAN_FFI_CHECKED_DELETE(ec_scalar);
×
218
}
219

220
int botan_ec_scalar_random(botan_ec_scalar_t* ec_scalar, botan_ec_group_t ec_group, botan_rng_t rng) {
×
221
   if(Botan::any_null_pointers(ec_scalar)) {
×
222
      return BOTAN_FFI_ERROR_NULL_POINTER;
223
   }
224
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
225
      return ffi_new_object(ec_scalar, std::make_unique<Botan::EC_Scalar>(Botan::EC_Scalar::random(g, safe_get(rng))));
226
   });
227
}
228

229
int botan_ec_scalar_one(botan_ec_scalar_t* ec_scalar, botan_ec_group_t ec_group) {
×
230
   if(Botan::any_null_pointers(ec_scalar)) {
×
231
      return BOTAN_FFI_ERROR_NULL_POINTER;
232
   }
233
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
234
      return ffi_new_object(ec_scalar, std::make_unique<Botan::EC_Scalar>(Botan::EC_Scalar::one(g)));
235
   });
236
}
237

238
int botan_ec_scalar_from_mp(botan_ec_scalar_t* ec_scalar, botan_ec_group_t ec_group, botan_mp_t mp) {
×
239
   if(Botan::any_null_pointers(ec_scalar)) {
×
240
      return BOTAN_FFI_ERROR_NULL_POINTER;
241
   }
242
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
243
      return ffi_new_object(ec_scalar,
244
                            std::make_unique<Botan::EC_Scalar>(Botan::EC_Scalar::from_bigint(g, safe_get(mp))));
245
   });
246
}
247

248
int botan_ec_scalar_view_bytes(botan_ec_scalar_t ec_scalar, botan_view_ctx ctx, botan_view_bin_fn view) {
×
249
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
250
      auto bytes = s.serialize();
251
      return invoke_view_callback(view, ctx, bytes);
252
   });
253
}
254

255
int botan_ec_scalar_to_mp(botan_ec_scalar_t ec_scalar, botan_mp_t* mp) {
×
256
   if(Botan::any_null_pointers(mp)) {
×
257
      return BOTAN_FFI_ERROR_NULL_POINTER;
258
   }
259
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
260
      return ffi_new_object(mp, std::make_unique<Botan::BigInt>(s.to_bigint()));
261
   });
262
}
263

264
int botan_ec_scalar_is_zero(botan_ec_scalar_t ec_scalar) {
×
265
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int { return s.is_zero() ? 1 : 0; });
×
266
}
267

268
int botan_ec_scalar_is_nonzero(botan_ec_scalar_t ec_scalar) {
×
269
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int { return s.is_nonzero() ? 1 : 0; });
×
270
}
271

272
int botan_ec_scalar_is_eq(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t x) {
×
273
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int { return s.is_eq(safe_get(x)) ? 1 : 0; });
×
274
}
275

276
int botan_ec_scalar_gk_x_mod_order(botan_ec_scalar_t ec_scalar, botan_rng_t rng, botan_ec_scalar_t* res) {
×
277
   if(Botan::any_null_pointers(res)) {
×
278
      return BOTAN_FFI_ERROR_NULL_POINTER;
279
   }
280
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) {
×
281
      return ffi_new_object(res,
282
                            std::make_unique<Botan::EC_Scalar>(Botan::EC_Scalar::gk_x_mod_order(s, safe_get(rng))));
283
   });
284
}
285

286
int botan_ec_scalar_g_mul(botan_ec_scalar_t scalar, botan_rng_t rng, botan_ec_point_t* res) {
×
287
   if(Botan::any_null_pointers(res)) {
×
288
      return BOTAN_FFI_ERROR_NULL_POINTER;
289
   }
290
   return ffi_guard_thunk(__func__, [=]() -> int {
×
291
      Botan::EC_AffinePoint pt = Botan::EC_AffinePoint::g_mul(safe_get(scalar), safe_get(rng));
×
292
      return ffi_new_object(res, std::make_unique<Botan::EC_AffinePoint>(pt));
×
293
   });
×
294
}
295

296
int botan_ec_scalar_invert(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t* res) {
×
297
   if(Botan::any_null_pointers(res)) {
×
298
      return BOTAN_FFI_ERROR_NULL_POINTER;
299
   }
300
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
301
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.invert()));
302
   });
303
}
304

305
int botan_ec_scalar_invert_vartime(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t* res) {
×
306
   if(Botan::any_null_pointers(res)) {
×
307
      return BOTAN_FFI_ERROR_NULL_POINTER;
308
   }
309
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
310
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.invert_vartime()));
311
   });
312
}
313

314
int botan_ec_scalar_negate(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t* res) {
×
315
   if(Botan::any_null_pointers(res)) {
×
316
      return BOTAN_FFI_ERROR_NULL_POINTER;
317
   }
318
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
319
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.negate()));
320
   });
321
}
322

323
int botan_ec_scalar_add(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t x, botan_ec_scalar_t* res) {
×
324
   if(Botan::any_null_pointers(res)) {
×
325
      return BOTAN_FFI_ERROR_NULL_POINTER;
326
   }
327
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
328
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.add(safe_get(x))));
329
   });
330
}
331

332
int botan_ec_scalar_sub(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t x, botan_ec_scalar_t* res) {
×
333
   if(Botan::any_null_pointers(res)) {
×
334
      return BOTAN_FFI_ERROR_NULL_POINTER;
335
   }
336
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
337
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.sub(safe_get(x))));
338
   });
339
}
340

341
int botan_ec_scalar_mul(botan_ec_scalar_t ec_scalar, botan_ec_scalar_t x, botan_ec_scalar_t* res) {
×
342
   if(Botan::any_null_pointers(res)) {
×
343
      return BOTAN_FFI_ERROR_NULL_POINTER;
344
   }
345
   return BOTAN_FFI_VISIT(ec_scalar, [=](const auto& s) -> int {
×
346
      return ffi_new_object(res, std::make_unique<Botan::EC_Scalar>(s.mul(safe_get(x))));
347
   });
348
}
349

350
int botan_ec_scalar_square(botan_ec_scalar_t ec_scalar) {
×
351
   return BOTAN_FFI_VISIT(ec_scalar, [=](auto& s) -> int {
×
352
      s.square_self();
353
      return BOTAN_FFI_SUCCESS;
354
   });
355
}
356

357
// ec points
358

359
int botan_ec_point_destroy(botan_ec_point_t ec_point) {
×
360
   return BOTAN_FFI_CHECKED_DELETE(ec_point);
×
361
}
362

363
int botan_ec_point_from_bytes(botan_ec_point_t* ec_point,
×
364
                              botan_ec_group_t ec_group,
365
                              const uint8_t* bytes,
366
                              size_t bytes_len) {
367
   if(Botan::any_null_pointers(ec_point, bytes)) {
×
368
      return BOTAN_FFI_ERROR_NULL_POINTER;
369
   }
370
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
371
      Botan::EC_AffinePoint pt(g, std::span{bytes, bytes_len});
372
      return ffi_new_object(ec_point, std::make_unique<Botan::EC_AffinePoint>(std::move(pt)));
373
   });
374
}
375

376
int botan_ec_point_from_xy(botan_ec_point_t* ec_point, botan_ec_group_t ec_group, botan_mp_t x, botan_mp_t y) {
×
377
   if(Botan::any_null_pointers(ec_point)) {
×
378
      return BOTAN_FFI_ERROR_NULL_POINTER;
379
   }
380
   return ffi_guard_thunk(__func__, [=]() -> int {
×
381
      std::optional<Botan::EC_AffinePoint> pt =
×
382
         Botan::EC_AffinePoint::from_bigint_xy(safe_get(ec_group), safe_get(x), safe_get(y));
×
383
      if(!pt.has_value()) {
×
384
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
385
      }
386

387
      return ffi_new_object(ec_point, std::make_unique<Botan::EC_AffinePoint>(pt.value()));
×
388
   });
×
389
}
390

391
int botan_ec_point_identity(botan_ec_point_t* ec_point, botan_ec_group_t ec_group) {
×
392
   if(Botan::any_null_pointers(ec_point)) {
×
393
      return BOTAN_FFI_ERROR_NULL_POINTER;
394
   }
395
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
396
      return ffi_new_object(ec_point, std::make_unique<Botan::EC_AffinePoint>(Botan::EC_AffinePoint::identity(g)));
397
   });
398
}
399

400
int botan_ec_point_generator(botan_ec_point_t* ec_point, botan_ec_group_t ec_group) {
×
401
   if(Botan::any_null_pointers(ec_point)) {
×
402
      return BOTAN_FFI_ERROR_NULL_POINTER;
403
   }
404
   return BOTAN_FFI_VISIT(ec_group, [=](const auto& g) -> int {
×
405
      return ffi_new_object(ec_point, std::make_unique<Botan::EC_AffinePoint>(Botan::EC_AffinePoint::generator(g)));
406
   });
407
}
408

409
int botan_ec_point_view_x_bytes(botan_ec_point_t ec_point, botan_view_ctx ctx, botan_view_bin_fn view) {
×
410
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int {
×
411
      auto bytes = p.x_bytes();
412
      return invoke_view_callback(view, ctx, bytes);
413
   });
414
}
415

416
int botan_ec_point_view_y_bytes(botan_ec_point_t ec_point, botan_view_ctx ctx, botan_view_bin_fn view) {
×
417
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int {
×
418
      auto bytes = p.y_bytes();
419
      return invoke_view_callback(view, ctx, bytes);
420
   });
421
}
422

423
int botan_ec_point_view_xy_bytes(botan_ec_point_t ec_point, botan_view_ctx ctx, botan_view_bin_fn view) {
×
424
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int {
×
425
      auto bytes = p.xy_bytes();
426
      return invoke_view_callback(view, ctx, bytes);
427
   });
428
}
429

430
int botan_ec_point_view_uncompressed(botan_ec_point_t ec_point, botan_view_ctx ctx, botan_view_bin_fn view) {
×
431
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int {
×
432
      auto bytes = p.serialize_uncompressed();
433
      return invoke_view_callback(view, ctx, bytes);
434
   });
435
}
436

437
int botan_ec_point_view_compressed(botan_ec_point_t ec_point, botan_view_ctx ctx, botan_view_bin_fn view) {
×
438
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int {
×
439
      auto bytes = p.serialize_compressed();
440
      return invoke_view_callback(view, ctx, bytes);
441
   });
442
}
443

444
int botan_ec_point_is_identity(botan_ec_point_t ec_point) {
×
445
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int { return p.is_identity() ? 1 : 0; });
×
446
}
447

448
int botan_ec_point_is_eq(botan_ec_point_t ec_point, botan_ec_point_t other) {
×
449
   return BOTAN_FFI_VISIT(ec_point, [=](const auto& p) -> int { return p == safe_get(other) ? 1 : 0; });
×
450
}
451

452
int botan_ec_point_mul(botan_ec_point_t ec_point, botan_ec_scalar_t scalar, botan_rng_t rng, botan_ec_point_t* res) {
×
453
   if(Botan::any_null_pointers(res)) {
×
454
      return BOTAN_FFI_ERROR_NULL_POINTER;
455
   }
456
   return BOTAN_FFI_VISIT(ec_point, [=](auto& pt) -> int {
×
457
      Botan::EC_AffinePoint out = pt.mul(safe_get(scalar), safe_get(rng));
458
      return ffi_new_object(res, std::make_unique<Botan::EC_AffinePoint>(out));
459
   });
460
}
461

462
int botan_ec_point_negate(botan_ec_point_t ec_point, botan_ec_point_t* res) {
×
463
   if(Botan::any_null_pointers(res)) {
×
464
      return BOTAN_FFI_ERROR_NULL_POINTER;
465
   }
466
   return BOTAN_FFI_VISIT(ec_point, [=](auto& pt) -> int {
×
467
      Botan::EC_AffinePoint out = pt.negate();
468
      return ffi_new_object(res, std::make_unique<Botan::EC_AffinePoint>(out));
469
   });
470
}
471

472
int botan_ec_point_add(botan_ec_point_t ec_point, botan_ec_point_t q, botan_ec_point_t* res) {
×
473
   if(Botan::any_null_pointers(res)) {
×
474
      return BOTAN_FFI_ERROR_NULL_POINTER;
475
   }
476
   return BOTAN_FFI_VISIT(ec_point, [=](auto& pt) -> int {
×
477
      Botan::EC_AffinePoint out = pt.add(safe_get(q));
478
      return ffi_new_object(res, std::make_unique<Botan::EC_AffinePoint>(out));
479
   });
480
}
481
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc