x448.c
Go to the documentation of this file.
1 /**
2  * @file x448.c
3  * @brief X448 function implementation
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
34 #include "ecc/ec_curves.h"
35 #include "ecc/curve448.h"
36 #include "ecc/x448.h"
37 #include "debug.h"
38 
39 //Check crypto library configuration
40 #if (X448_SUPPORT == ENABLED)
41 
42 
43 /**
44  * @brief X448 function (scalar multiplication on Curve448)
45  * @param[out] r Output u-coordinate
46  * @param[in] k Input scalar
47  * @param[in] u Input u-coordinate
48  * @return Error code
49  **/
50 
51 error_t x448(uint8_t *r, const uint8_t *k, const uint8_t *u)
52 {
53  int_t i;
54  uint32_t b;
55  uint32_t swap;
56  X448State *state;
57 
58  //Check parameters
59  if(r == NULL || k == NULL || u == NULL)
61 
62  //Allocate working state
63  state = cryptoAllocMem(sizeof(X448State));
64  //Failed to allocate memory?
65  if(state == NULL)
66  return ERROR_OUT_OF_MEMORY;
67 
68  //Copy scalar
69  curve448Import(state->k, k);
70 
71  //Set the two least significant bits of the first byte to 0, and the most
72  //significant bit of the last byte to 1
73  state->k[0] &= 0xFFFFFFFC;
74  state->k[13] |= 0x80000000;
75 
76  //Copy input u-coordinate
77  curve448Import(state->u, u);
78 
79  //Implementations must accept non-canonical values and process them as
80  //if they had been reduced modulo the field prime (refer to RFC 7748,
81  //section 5)
82  curve448Red(state->u, state->u, 0);
83 
84  //Set X1 = 1
85  curve448SetInt(state->x1, 1);
86  //Set Z1 = 0
87  curve448SetInt(state->z1, 0);
88  //Set X2 = U
89  curve448Copy(state->x2, state->u);
90  //Set Z2 = 1
91  curve448SetInt(state->z2, 1);
92 
93  //Set swap = 0
94  swap = 0;
95 
96  //Montgomery ladder
97  for(i = CURVE448_BIT_LEN - 1; i >= 0; i--)
98  {
99  //The scalar is processed in a left-to-right fashion
100  b = (state->k[i / 32] >> (i % 32)) & 1;
101 
102  //Conditional swap
103  curve448Swap(state->x1, state->x2, swap ^ b);
104  curve448Swap(state->z1, state->z2, swap ^ b);
105 
106  //Save current bit value
107  swap = b;
108 
109  //Compute T1 = X2 + Z2
110  curve448Add(state->t1, state->x2, state->z2);
111  //Compute X2 = X2 - Z2
112  curve448Sub(state->x2, state->x2, state->z2);
113  //Compute Z2 = X1 + Z1
114  curve448Add(state->z2, state->x1, state->z1);
115  //Compute X1 = X1 - Z1
116  curve448Sub(state->x1, state->x1, state->z1);
117  //Compute T1 = T1 * X1
118  curve448Mul(state->t1, state->t1, state->x1);
119  //Compute X2 = X2 * Z2
120  curve448Mul(state->x2, state->x2, state->z2);
121  //Compute Z2 = Z2 * Z2
122  curve448Sqr(state->z2, state->z2);
123  //Compute X1 = X1 * X1
124  curve448Sqr(state->x1, state->x1);
125  //Compute T2 = Z2 - X1
126  curve448Sub(state->t2, state->z2, state->x1);
127  //Compute Z1 = T2 * a24
128  curve448MulInt(state->z1, state->t2, CURVE448_A24);
129  //Compute Z1 = Z1 + X1
130  curve448Add(state->z1, state->z1, state->x1);
131  //Compute Z1 = Z1 * T2
132  curve448Mul(state->z1, state->z1, state->t2);
133  //Compute X1 = X1 * Z2
134  curve448Mul(state->x1, state->x1, state->z2);
135  //Compute Z2 = T1 - X2
136  curve448Sub(state->z2, state->t1, state->x2);
137  //Compute Z2 = Z2 * Z2
138  curve448Sqr(state->z2, state->z2);
139  //Compute Z2 = Z2 * U
140  curve448Mul(state->z2, state->z2, state->u);
141  //Compute X2 = X2 + T1
142  curve448Add(state->x2, state->x2, state->t1);
143  //Compute X2 = X2 * X2
144  curve448Sqr(state->x2, state->x2);
145  }
146 
147  //Conditional swap
148  curve448Swap(state->x1, state->x2, swap);
149  curve448Swap(state->z1, state->z2, swap);
150 
151  //Retrieve affine representation
152  curve448Inv(state->u, state->z1);
153  curve448Mul(state->u, state->u, state->x1);
154 
155  //Copy output u-coordinate
156  curve448Export(state->u, r);
157 
158  //Erase working state
159  cryptoMemset(state, 0, sizeof(X448State));
160  //Release working state
161  cryptoFreeMem(state);
162 
163  //Successful processing
164  return NO_ERROR;
165 }
166 
167 #endif
void curve448Copy(uint32_t *a, const uint32_t *b)
Copy an integer.
Definition: curve448.c:526
void curve448Sqr(uint32_t *r, const uint32_t *a)
Modular squaring.
Definition: curve448.c:330
Curve448 elliptic curve (constant-time implementation)
void curve448MulInt(uint32_t *r, const uint32_t *a, uint32_t b)
Modular multiplication.
Definition: curve448.c:289
void curve448Swap(uint32_t *a, uint32_t *b, uint32_t c)
Conditional swap.
Definition: curve448.c:545
#define cryptoFreeMem(p)
Definition: crypto.h:578
Debugging facilities.
uint32_t x2[14]
Definition: x448.h:52
#define cryptoAllocMem(size)
Definition: crypto.h:573
General definitions for cryptographic algorithms.
Invalid parameter.
Definition: error.h:45
void curve448Red(uint32_t *r, const uint32_t *a, uint32_t h)
Modular reduction.
Definition: curve448.c:366
void curve448Add(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular addition.
Definition: curve448.c:70
Elliptic curves.
void curve448Sub(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular subtraction.
Definition: curve448.c:121
error_t x448(uint8_t *r, const uint8_t *k, const uint8_t *u)
X448 function (scalar multiplication on Curve448)
Definition: x448.c:51
void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: curve448.c:197
uint32_t k[14]
Definition: x448.h:48
signed int int_t
Definition: compiler_port.h:42
uint32_t z1[14]
Definition: x448.h:51
uint32_t t2[14]
Definition: x448.h:55
uint32_t z2[14]
Definition: x448.h:53
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
#define CURVE448_A24
Definition: curve448.h:41
uint32_t r
Definition: ndp.h:342
uint32_t t1[14]
Definition: x448.h:54
void curve448Import(uint32_t *a, const uint8_t *data)
Import an octet string.
Definition: curve448.c:624
#define cryptoMemset(p, value, length)
Definition: crypto.h:584
#define CURVE448_BIT_LEN
Definition: curve448.h:36
void curve448Inv(uint32_t *r, const uint32_t *a)
Modular multiplicative inverse.
Definition: curve448.c:401
X448 function implementation.
uint32_t x1[14]
Definition: x448.h:50
uint32_t u[14]
Definition: x448.h:49
X448 working state.
Definition: x448.h:46
uint8_t b[6]
Definition: dtls_misc.h:130
void curve448Export(uint32_t *a, uint8_t *data)
Export an octet string.
Definition: curve448.c:645
void curve448SetInt(uint32_t *a, uint32_t b)
Set integer value.
Definition: curve448.c:48