1 /*
2 * Copyright (c) 2024, The TrustedFirmware-M Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8
9 #include "cc3xx_ec_projective_point.h"
10
11 #include "cc3xx_config.h"
12 #include "cc3xx_pka.h"
13 #include "cc3xx_ec.h"
14
15 #include "fatal_error.h"
16
cc3xx_lowlevel_ec_allocate_projective_point(void)17 cc3xx_ec_point_projective cc3xx_lowlevel_ec_allocate_projective_point(void)
18 {
19 cc3xx_ec_point_projective res;
20
21 res.x = cc3xx_lowlevel_pka_allocate_reg();
22 res.y = cc3xx_lowlevel_pka_allocate_reg();
23 res.z = cc3xx_lowlevel_pka_allocate_reg();
24
25 return res;
26 }
27
cc3xx_lowlevel_ec_free_projective_point(cc3xx_ec_point_projective * p)28 void cc3xx_lowlevel_ec_free_projective_point(cc3xx_ec_point_projective *p)
29 {
30 cc3xx_lowlevel_pka_free_reg(p->z);
31 cc3xx_lowlevel_pka_free_reg(p->y);
32 cc3xx_lowlevel_pka_free_reg(p->x);
33 }
34
cc3xx_lowlevel_ec_projective_point_is_infinity(cc3xx_ec_point_projective * p)35 bool cc3xx_lowlevel_ec_projective_point_is_infinity(cc3xx_ec_point_projective *p)
36 {
37 return cc3xx_lowlevel_pka_are_equal_si(p->z, 0);
38 }
39
cc3xx_lowlevel_ec_copy_projective_point(cc3xx_ec_point_projective * p,cc3xx_ec_point_projective * res)40 void cc3xx_lowlevel_ec_copy_projective_point(cc3xx_ec_point_projective *p,
41 cc3xx_ec_point_projective *res)
42 {
43 cc3xx_lowlevel_pka_copy(p->x, res->x);
44 cc3xx_lowlevel_pka_copy(p->y, res->y);
45 cc3xx_lowlevel_pka_copy(p->z, res->z);
46 }
47
cc3xx_lowlevel_ec_affine_to_jacobian_with_random_z(cc3xx_ec_curve_t * curve,cc3xx_ec_point_affine * p,cc3xx_ec_point_projective * res)48 void cc3xx_lowlevel_ec_affine_to_jacobian_with_random_z(cc3xx_ec_curve_t *curve,
49 cc3xx_ec_point_affine *p,
50 cc3xx_ec_point_projective *res)
51 {
52 #ifndef CC3XX_CONFIG_DPA_MITIGATIONS_ENABLE
53 return cc3xx_lowlevel_ec_affine_to_jacobian(curve, p, res);
54 #endif
55
56 cc3xx_pka_reg_id_t temp = cc3xx_lowlevel_pka_allocate_reg();
57
58 /* Z is random, between 0 and N-1. Realistically, the RNG will never output
59 * 0.
60 */
61 do {
62 cc3xx_lowlevel_pka_set_to_random_within_modulus(res->z);
63 } while (cc3xx_lowlevel_pka_are_equal_si(res->z, 0));
64
65 /* Construct Z^2 */
66 cc3xx_lowlevel_pka_mod_mul(res->z, res->z, temp);
67
68 /* Divide X by Z^2 */
69 cc3xx_lowlevel_pka_mod_mul(p->x, temp, res->x);
70
71 /* Construct Z^3 */
72 cc3xx_lowlevel_pka_mod_mul(temp, res->z, temp);
73
74 /* Divide Y by Z^3 */
75 cc3xx_lowlevel_pka_mod_mul(p->y, temp, res->y);
76
77 cc3xx_lowlevel_pka_free_reg(temp);
78 }
79
cc3xx_lowlevel_ec_affine_to_jacobian(cc3xx_ec_curve_t * curve,cc3xx_ec_point_affine * p,cc3xx_ec_point_projective * res)80 void cc3xx_lowlevel_ec_affine_to_jacobian(cc3xx_ec_curve_t *curve,
81 cc3xx_ec_point_affine *p,
82 cc3xx_ec_point_projective *res)
83 {
84 cc3xx_lowlevel_pka_copy(p->x, res->x);
85 cc3xx_lowlevel_pka_copy(p->y, res->y);
86 cc3xx_lowlevel_pka_clear(res->z);
87 cc3xx_lowlevel_pka_add_si(res->z, 1, res->z);
88 }
89
cc3xx_lowlevel_ec_jacobian_to_affine(cc3xx_ec_curve_t * curve,cc3xx_ec_point_projective * p,cc3xx_ec_point_affine * res)90 cc3xx_err_t cc3xx_lowlevel_ec_jacobian_to_affine(cc3xx_ec_curve_t *curve,
91 cc3xx_ec_point_projective *p,
92 cc3xx_ec_point_affine *res)
93 {
94 if (cc3xx_lowlevel_ec_projective_point_is_infinity(p)) {
95 FATAL_ERR(CC3XX_ERR_EC_POINT_IS_INFINITY);
96 return CC3XX_ERR_EC_POINT_IS_INFINITY;
97 }
98
99 cc3xx_pka_reg_id_t z_inv = cc3xx_lowlevel_pka_allocate_reg();
100 cc3xx_pka_reg_id_t temp = cc3xx_lowlevel_pka_allocate_reg();
101
102 /* Construct 1/(Z^2) */
103 cc3xx_lowlevel_pka_mod_inv(p->z, z_inv);
104 cc3xx_lowlevel_pka_mod_mul(z_inv, z_inv, temp);
105
106 /* Divide X by Z^2 */
107 cc3xx_lowlevel_pka_mod_mul(p->x, temp, res->x);
108
109 /* Construct 1/(Z^3) */
110 cc3xx_lowlevel_pka_mod_mul(temp, z_inv, temp);
111
112 /* Divide Y by Z^3 */
113 cc3xx_lowlevel_pka_mod_mul(p->y, temp, res->y);
114
115 cc3xx_lowlevel_pka_free_reg(temp);
116 cc3xx_lowlevel_pka_free_reg(z_inv);
117
118 return CC3XX_ERR_SUCCESS;
119 }
120