Elliptic Curve (Ed25519) and Field Arithmetic Implementation. More...
#include "common.h"
Go to the source code of this file.
Data Structures | |
struct | ge25519_p2 |
Projective coordinate representation. More... | |
struct | ge25519_p3 |
Extended projective coordinate representation. More... | |
struct | ge25519_p1p1 |
Intermediate coordinate representation. More... | |
struct | ge25519_precomp |
Precomputed point representation. More... | |
struct | ge25519_cached |
Cached point representation. More... | |
Typedefs | |
typedef QSC_SIMD_ALIGN int32_t | fe25519[10] |
The ecc fe25519 polynomial. | |
Functions | |
void | fe25519_0 (fe25519 h) |
Set a field element to zero. | |
void | fe25519_1 (fe25519 h) |
Set a field element to one. | |
void | fe25519_copy (fe25519 h, const fe25519 f) |
Copy a field element. | |
void | fe25519_add (fe25519 h, const fe25519 f, const fe25519 g) |
Add two field elements. | |
void | fe25519_cswap (fe25519 f, fe25519 g, uint32_t b) |
Conditionally swap two field elements in constant time. | |
void | fe25519_sub (fe25519 h, const fe25519 f, const fe25519 g) |
Subtract one field element from another. | |
void | fe25519_neg (fe25519 h, const fe25519 f) |
Negate a field element. | |
void | fe25519_cmov (fe25519 f, const fe25519 g, uint32_t b) |
Conditionally move a field element in constant time. | |
int32_t | fe25519_isnegative (const fe25519 f) |
Determine if a field element is negative. | |
int32_t | fe25519_iszero (const fe25519 f) |
Determine if a field element is zero. | |
void | fe25519_mul (fe25519 h, const fe25519 f, const fe25519 g) |
Multiply two field elements. | |
void | fe25519_mul32 (fe25519 h, const fe25519 f, uint32_t n) |
Multiply a field element by a scalar. | |
void | fe25519_sq (fe25519 h, const fe25519 f) |
Square a field element. | |
void | fe25519_sq2 (fe25519 h, const fe25519 f) |
Compute 2 * f^2. | |
void | fe25519_frombytes (fe25519 h, const uint8_t *s) |
Convert a 32-byte array to a field element. | |
void | fe25519_reduce (fe25519 h, const fe25519 f) |
Reduce a field element modulo 2^255 - 19. | |
void | fe25519_tobytes (uint8_t *s, const fe25519 h) |
Convert a field element to a 32-byte array. | |
void | fe25519_invert (fe25519 out, const fe25519 z) |
Compute the multiplicative inverse of a field element. | |
void | ge25519_p1p1_to_p3 (ge25519_p3 *r, const ge25519_p1p1 *p) |
Convert a point from P1P1 to P3 coordinates. | |
void | ge25519_p1p1_to_p2 (ge25519_p2 *r, const ge25519_p1p1 *p) |
Convert a point from P1P1 to P2 coordinates. | |
void | ge25519_scalarmult_base (ge25519_p3 *h, const uint8_t *a) |
Multiply the base point by a scalar. | |
void | ge25519_p3_tobytes (uint8_t *s, const ge25519_p3 *h) |
Compress a point in P3 coordinates to a 32-byte representation. | |
int32_t | ge25519_is_canonical (const uint8_t *s) |
Check if a compressed point is canonical. | |
int32_t | ge25519_has_small_order (const uint8_t s[32]) |
Determine if a compressed point has small order. | |
int32_t | ge25519_frombytes_negate_vartime (ge25519_p3 *h, const uint8_t *s) |
Decode and conditionally negate a compressed point. | |
void | ge25519_p3_to_cached (ge25519_cached *r, const ge25519_p3 *p) |
Convert a point from P3 coordinates to a cached representation. | |
void | ge25519_add_cached (ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) |
Add a cached point to a point. | |
void | ge25519_sub_precomp (ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) |
Subtract a precomputed point from a point. | |
void | ge25519_double_scalarmult_vartime (ge25519_p2 *r, const uint8_t *a, const ge25519_p3 *A, const uint8_t *b) |
Compute a double scalar multiplication. | |
void | ge25519_sub_cached (ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) |
Subtract a cached point from a point. | |
void | ge25519_tobytes (uint8_t *s, const ge25519_p2 *h) |
Compress a point in P2 coordinates to a 32-byte representation. | |
void | sc25519_clamp (uint8_t *k) |
Clamp a secret scalar. | |
int32_t | ed25519_small_order (const uint8_t s[32]) |
Check if a compressed point has small order. | |
int32_t | sc25519_is_canonical (const uint8_t s[32]) |
Check if a scalar is canonical. | |
void | sc25519_muladd (uint8_t s[32], const uint8_t a[32], const uint8_t b[32], const uint8_t c[32]) |
Compute s = a * b + c for scalars. | |
void | sc25519_reduce (uint8_t s[64]) |
Reduce a 64-byte scalar modulo 2^255 - 19. | |
int32_t | qsc_sc25519_verify (const uint8_t *x, const uint8_t *y, const size_t n) |
Performs a constant-time comparison of two byte arrays. | |
Elliptic Curve (Ed25519) and Field Arithmetic Implementation.
This header defines the data structures and functions for performing operations on the Ed25519 elliptic curve, which is widely used for digital signatures and key exchange protocols. It provides several coordinate representations for curve points, including:
In addition, this header defines functions for field arithmetic in the finite field defined by 2^255 - 19. Field elements are represented as arrays of 10 int32_t values in a radix-2^25.5 format. The field arithmetic functions include:
These operations form the foundation of the Ed25519 digital signature scheme and key exchange protocols and are implemented to be constant-time to mitigate timing attacks.
int32_t ed25519_small_order | ( | const uint8_t | s[32] | ) |
Check if a compressed point has small order.
Determines whether the given 32-byte compressed point is of small order, which is insecure for cryptographic operations.
s | [const uint8_t[32]] The 32-byte compressed point. |
void fe25519_0 | ( | fe25519 | h | ) |
Set a field element to zero.
Sets all limbs of the field element h to 0.
h | [fe25519] The field element to zero. |
void fe25519_1 | ( | fe25519 | h | ) |
Set a field element to one.
Initializes the field element h to the multiplicative identity (1).
h | [fe25519] The field element to set to one. |
Conditionally move a field element in constant time.
Conditionally moves the field element g into f if the condition bit b is set. This operation is performed in constant time.
Conditionally swap two field elements in constant time.
Conditionally swaps the field elements f and g if the condition bit b is nonzero. This function operates in constant time to prevent timing attacks.
void fe25519_frombytes | ( | fe25519 | h, |
const uint8_t * | s ) |
Convert a 32-byte array to a field element.
Interprets a 32-byte little-endian array s as a field element and stores it in h.
h | [fe25519] Destination field element. |
s | [const uint8_t*] Source byte array. |
int32_t fe25519_isnegative | ( | const fe25519 | f | ) |
Determine if a field element is negative.
Converts the field element f to its 32-byte representation and returns the least significant bit.
f | [const fe25519] The field element to check. |
int32_t fe25519_iszero | ( | const fe25519 | f | ) |
Determine if a field element is zero.
Converts the field element f to its 32-byte representation and checks if all bytes are zero.
f | [const fe25519] The field element to check. |
Subtract one field element from another.
Computes the difference h = f - g.
h | [fe25519] Destination field element. |
f | [const fe25519] Minuend field element. |
g | [const fe25519] Subtrahend field element. |
void fe25519_tobytes | ( | uint8_t * | s, |
const fe25519 | h ) |
Convert a field element to a 32-byte array.
Serializes the field element h into a 32-byte little-endian representation stored in s.
s | [uint8_t*] Destination byte array. |
h | [const fe25519] Field element to serialize. |
void ge25519_add_cached | ( | ge25519_p1p1 * | r, |
const ge25519_p3 * | p, | ||
const ge25519_cached * | q ) |
Add a cached point to a point.
Computes the sum of a point in P3 coordinates and a cached point, storing the result in the P1P1 representation.
r | [ge25519_p1p1*] Pointer to the output point in P1P1 coordinates. |
p | [const ge25519_p3*] Pointer to the input point in P3 coordinates. |
q | [const ge25519_cached*] Pointer to the cached point. |
void ge25519_double_scalarmult_vartime | ( | ge25519_p2 * | r, |
const uint8_t * | a, | ||
const ge25519_p3 * | A, | ||
const uint8_t * | b ) |
Compute a double scalar multiplication.
Computes the expression r = a * A + b * B, where A is an arbitrary point and B is the base point. The result is returned in the P2 coordinate representation using a variable-time algorithm.
r | [ge25519_p2*] Pointer to the output point in P2 coordinates. |
a | [const uint8_t*] Pointer to the scalar for point A. |
A | [const ge25519_p3*] Pointer to the point A in P3 coordinates. |
b | [const uint8_t*] Pointer to the scalar for the base point. |
int32_t ge25519_frombytes_negate_vartime | ( | ge25519_p3 * | h, |
const uint8_t * | s ) |
Decode and conditionally negate a compressed point.
Decodes a 32-byte compressed point into extended P3 coordinates and conditionally negates the X-coordinate to enforce a canonical representation.
h | [ge25519_p3*] Pointer to the output point in P3 coordinates. |
s | [const uint8_t*] Pointer to the 32-byte compressed point. |
int32_t ge25519_has_small_order | ( | const uint8_t | s[32] | ) |
Determine if a compressed point has small order.
Checks whether the given 32-byte compressed point has small order, which is considered insecure.
s | [const uint8_t[32]] The 32-byte compressed point. |
int32_t ge25519_is_canonical | ( | const uint8_t * | s | ) |
Check if a compressed point is canonical.
Verifies whether the given 32-byte compressed point is in canonical form.
s | [const uint8_t*] Pointer to the 32-byte compressed representation. |
void ge25519_p1p1_to_p2 | ( | ge25519_p2 * | r, |
const ge25519_p1p1 * | p ) |
Convert a point from P1P1 to P2 coordinates.
Converts a point in the intermediate P1P1 coordinate system to the projective P2 representation.
r | [ge25519_p2*] Pointer to the output point in P2 coordinates. |
p | [const ge25519_p1p1*] Pointer to the input point in P1P1 coordinates. |
void ge25519_p1p1_to_p3 | ( | ge25519_p3 * | r, |
const ge25519_p1p1 * | p ) |
Convert a point from P1P1 to P3 coordinates.
Converts a point in the intermediate P1P1 coordinate system to the extended P3 representation.
r | [ge25519_p3*] Pointer to the output point in P3 coordinates. |
p | [const ge25519_p1p1*] Pointer to the input point in P1P1 coordinates. |
void ge25519_p3_to_cached | ( | ge25519_cached * | r, |
const ge25519_p3 * | p ) |
Convert a point from P3 coordinates to a cached representation.
Converts a point in extended P3 coordinates into a cached format to accelerate point addition.
r | [ge25519_cached*] Pointer to the output cached point. |
p | [const ge25519_p3*] Pointer to the input point in P3 coordinates. |
void ge25519_p3_tobytes | ( | uint8_t * | s, |
const ge25519_p3 * | h ) |
Compress a point in P3 coordinates to a 32-byte representation.
Converts a point in extended P3 coordinates to its compressed 32-byte form.
s | [uint8_t*] Pointer to the output 32-byte array. |
h | [const ge25519_p3*] Pointer to the input point in P3 coordinates. |
void ge25519_scalarmult_base | ( | ge25519_p3 * | h, |
const uint8_t * | a ) |
Multiply the base point by a scalar.
Computes the scalar multiplication h = a * BasePoint, where a is a 32-byte scalar.
h | [ge25519_p3*] Pointer to the output point in P3 coordinates. |
a | [const uint8_t*] Pointer to a 32-byte scalar. |
void ge25519_sub_cached | ( | ge25519_p1p1 * | r, |
const ge25519_p3 * | p, | ||
const ge25519_cached * | q ) |
Subtract a cached point from a point.
Computes the difference r = p - q, where p is in P3 coordinates and q is in cached form, storing the result in the P1P1 representation.
r | [ge25519_p1p1*] Pointer to the output point in P1P1 coordinates. |
p | [const ge25519_p3*] Pointer to the input point in P3 coordinates. |
q | [const ge25519_cached*] Pointer to the cached point. |
void ge25519_sub_precomp | ( | ge25519_p1p1 * | r, |
const ge25519_p3 * | p, | ||
const ge25519_precomp * | q ) |
Subtract a precomputed point from a point.
Computes the subtraction r = p - q, where p is in P3 coordinates and q is in precomputed form, and stores the result in the P1P1 representation.
r | [ge25519_p1p1*] Pointer to the output point in P1P1 coordinates. |
p | [const ge25519_p3*] Pointer to the input point in P3 coordinates. |
q | [const ge25519_precomp*] Pointer to the precomputed point. |
void ge25519_tobytes | ( | uint8_t * | s, |
const ge25519_p2 * | h ) |
Compress a point in P2 coordinates to a 32-byte representation.
Converts a point in the P2 coordinate representation to its compressed 32-byte form.
s | [uint8_t*] Pointer to the output 32-byte array. |
h | [const ge25519_p2*] Pointer to the input point in P2 coordinates. |
int32_t qsc_sc25519_verify | ( | const uint8_t * | x, |
const uint8_t * | y, | ||
const size_t | n ) |
Performs a constant-time comparison of two byte arrays.
This function compares two byte arrays, x and y, each of length n, in constant time. It computes the bitwise XOR for each corresponding byte and accumulates the result using bitwise OR. The final result is processed to return 0 if the arrays are identical, or -1 if any byte differs.
x | [const uint8_t*] Pointer to the first byte array. |
y | [const uint8_t*] Pointer to the second byte array. |
n | [size_t] The number of bytes to compare. |
void sc25519_clamp | ( | uint8_t * | k | ) |
Clamp a secret scalar.
Clamps the 32-byte secret scalar to ensure it conforms to the Ed25519 key format.
k | [uint8_t*] Pointer to the 32-byte scalar to be clamped. |
int32_t sc25519_is_canonical | ( | const uint8_t | s[32] | ) |
Check if a scalar is canonical.
Verifies that the given 32-byte scalar is in its canonical form.
s | [const uint8_t[32]] Pointer to the 32-byte scalar. |
void sc25519_muladd | ( | uint8_t | s[32], |
const uint8_t | a[32], | ||
const uint8_t | b[32], | ||
const uint8_t | c[32] ) |
Compute s = a * b + c for scalars.
Computes the scalar multiplication of two 32-byte scalars a and b, adds a third scalar c, and stores the result in s.
s | [uint8_t[32]] Output scalar. |
a | [const uint8_t[32]] The first scalar operand. |
b | [const uint8_t[32]] The second scalar operand. |
c | [const uint8_t[32]] The scalar addend. |
void sc25519_reduce | ( | uint8_t | s[64] | ) |
Reduce a 64-byte scalar modulo 2^255 - 19.
This function takes a 64-byte little-endian representation of an integer and reduces it modulo the prime 2^255 - 19, producing a canonical form suitable for use as a field element in the Ed25519 elliptic curve. The reduction is performed by splitting the input into 24 limbs (each containing up to 21 or 26 bits), then applying a series of multiplications, additions, subtractions, and carry propagations.
The algorithm is carefully optimized to handle the non-uniform limb sizes and ensures that the final output fits within the desired bit bounds for each limb. The result is written back into the input array s
, replacing its original contents.
s | [uint8_t*] A pointer to a 64-byte array representing the scalar to be reduced. |