Skip to content

File syn_p256.c

FileList > crypto > syn_p256.c

Go to the source code of this file

NIST P-256 (secp256r1 / prime256v1) Elliptic Curve Cryptography implementation.

  • #include "syn_p256.h"
  • #include "syn_hmac_drbg.h"
  • #include <string.h>

Classes

Type Name
struct P256_Point
Point representation in Jacobian projective coordinates (X, Y, Z).

Public Types

Type Name
typedef uint32_t bignum256
256-bit unsigned big integer representation in eight 32-bit limbs.

Public Static Attributes

Type Name
const uint32_t BN_ONE = {1U, 0U, 0U, 0U, 0U, 0U, 0U, 0U}
Big-number 1.
const uint32_t P256_B = /* multi line expression */
Curve coefficient b.
const uint32_t P256_GX = /* multi line expression */
Base Generator G x-coordinate.
const uint32_t P256_GY = /* multi line expression */
Base Generator G y-coordinate.
const uint32_t P256_N = /* multi line expression */
Group order n.
const uint32_t P256_P = /* multi line expression */
Prime p = 2^256 - 2^224 + 2^192 + 2^96 - 1.

Public Functions

Type Name
bool syn_p256_base_mul (const uint8_t scalar, uint8_t pub_x, uint8_t pub_y)
Multiply the P-256 base generator G by a 32-byte scalar.
bool syn_p256_ecdh (const uint8_t priv_key, const uint8_t peer_pub_x, const uint8_t peer_pub_y, uint8_t shared_secret)
Perform ECDH Key Agreement.
bool syn_p256_is_on_curve (const uint8_t px, const uint8_t py)
Validate if a point (x, y) lies on the NIST P-256 curve: y^2 = x^3 - 3x + b (mod p).
bool syn_p256_point_mul (const uint8_t scalar, const uint8_t px, const uint8_t py, uint8_t rx, uint8_t ry)
Multiply an arbitrary P-256 point by a 32-byte scalar.
bool syn_p256_sign_ecdsa (const uint8_t priv_key, const uint8_t nonce_k, const uint8_t hash, uint8_t r_out, uint8_t s_out)
Generate a NIST P-256 ECDSA signature (FIPS 186-4).
bool syn_p256_sign_ecdsa_deterministic (const uint8_t priv_key, const uint8_t hash, uint8_t r_out, uint8_t s_out)
Generate a deterministic NIST P-256 ECDSA signature (RFC 6979 / FIPS 186-4).
bool syn_p256_verify_ecdsa (const uint8_t hash, const uint8_t r, const uint8_t s, const uint8_t pub_x, const uint8_t pub_y)
Verify a NIST P-256 ECDSA signature (FIPS 186-4).

Public Static Functions

Type Name
uint32_t bn_add_raw (bignum256 r, const bignum256 a, const bignum256 b)
Raw 256-bit addition with carry out.
int bn_cmp (const bignum256 a, const bignum256 b)
Compare two 256-bit big numbers.
void bn_copy (bignum256 r, const bignum256 a)
Copy bignum256.
void bn_div2_mod_n (bignum256 r, const bignum256 a)
Halving modulo n: computes (a / 2) mod n.
void bn_from_bytes (bignum256 r, const uint8_t bytes)
Load bignum256 from 32 big-endian bytes.
bool bn_is_zero (const bignum256 a)
Check if bignum256 is zero.
void bn_mul_raw (uint32_t t, const bignum256 a, const bignum256 b)
256x256-bit raw integer multiplication producing a 512-bit product.
void bn_rshift1 (bignum256 r, const bignum256 a)
Shift 256-bit bignum right by 1 bit.
uint32_t bn_sub_raw (bignum256 r, const bignum256 a, const bignum256 b)
Raw 256-bit subtraction with borrow out.
void bn_to_bytes (uint8_t bytes, const bignum256 a)
Export bignum256 to 32 big-endian bytes.
void p256_mod_n_inv (bignum256 r, const bignum256 a)
Group order inversion modulo n via Binary Extended Euclidean Algorithm: a^(-1) mod n.
void p256_mod_n_mul (bignum256 r, const bignum256 a, const bignum256 b)
Group order multiplication modulo n.
void p256_mod_n_sub (bignum256 r, const bignum256 a, const bignum256 b)
Subtraction modulo n.
void p256_mod_p_add (bignum256 r, const bignum256 a, const bignum256 b)
Field addition modulo p.
void p256_mod_p_inv (bignum256 r, const bignum256 a)
Field inversion modulo p via Fermat's Little Theorem: a^(p-2) mod p.
void p256_mod_p_mul (bignum256 r, const bignum256 a, const bignum256 b)
Field multiplication modulo p.
void p256_mod_p_reduce (bignum256 r, const uint32_t c)
512-bit integer fast reduction modulo p using Solinas algorithm for NIST P-256.
void p256_mod_p_sqr (bignum256 r, const bignum256 a)
Field squaring modulo p.
void p256_mod_p_sub (bignum256 r, const bignum256 a, const bignum256 b)
Field subtraction modulo p.
void point_add (P256_Point * r, const P256_Point * p, const P256_Point * q)
Point Addition in Jacobian coordinates: P + Q.
void point_add_mixed (P256_Point * r, const P256_Point * p, const bignum256 qx, const bignum256 qy)
Mixed Jacobian + Affine Addition: P (Jacobian) + Q (Affine).
void point_cmov (P256_Point * dst, const P256_Point * src, uint32_t mask)
Constant-time conditional point move: dst = (mask != 0) ? src : dst.
void point_double (P256_Point * r, const P256_Point * p)
Point Doubling in Jacobian coordinates: 2P.
void point_scalar_mul_affine (P256_Point * r, const bignum256 k, const bignum256 px, const bignum256 py)
Constant-time Windowed Scalar Multiplication: k * P (where P is affine (px, py)).
void point_set_infinity (P256_Point * p)
Set Jacobian point to infinity.
void point_to_affine (const P256_Point * p, bignum256 x_out, bignum256 y_out)
Convert Jacobian coordinates (X, Y, Z) to Affine coordinates (x, y).

Public Types Documentation

typedef bignum256

256-bit unsigned big integer representation in eight 32-bit limbs.

typedef uint32_t bignum256[8];


Public Static Attributes Documentation

variable BN_ONE

Big-number 1.

const uint32_t BN_ONE[8];


variable P256_B

Curve coefficient b.

const uint32_t P256_B[8];


variable P256_GX

Base Generator G x-coordinate.

const uint32_t P256_GX[8];


variable P256_GY

Base Generator G y-coordinate.

const uint32_t P256_GY[8];


variable P256_N

Group order n.

const uint32_t P256_N[8];


variable P256_P

Prime p = 2^256 - 2^224 + 2^192 + 2^96 - 1.

const uint32_t P256_P[8];


Public Functions Documentation

function syn_p256_base_mul

Multiply the P-256 base generator G by a 32-byte scalar.

bool syn_p256_base_mul (
    const uint8_t scalar,
    uint8_t pub_x,
    uint8_t pub_y
) 

Computes Q = scalar * G.

Parameters:

  • scalar 32-byte scalar in big-endian format.
  • pub_x [out] 32-byte X-coordinate of resulting point.
  • pub_y [out] 32-byte Y-coordinate of resulting point.

Returns:

true on success, false if scalar is 0 or >= curve order.


function syn_p256_ecdh

Perform ECDH Key Agreement.

bool syn_p256_ecdh (
    const uint8_t priv_key,
    const uint8_t peer_pub_x,
    const uint8_t peer_pub_y,
    uint8_t shared_secret
) 

Computes shared_secret = priv_key * peer_pub_point.

Parameters:

  • priv_key 32-byte private key scalar.
  • peer_pub_x 32-byte X-coordinate of peer's public key.
  • peer_pub_y 32-byte Y-coordinate of peer's public key.
  • shared_secret [out] 32-byte shared secret (X-coordinate of product point).

Returns:

true on success, false on invalid point or scalar.


function syn_p256_is_on_curve

Validate if a point (x, y) lies on the NIST P-256 curve: y^2 = x^3 - 3x + b (mod p).

bool syn_p256_is_on_curve (
    const uint8_t px,
    const uint8_t py
) 

Parameters:

  • px 32-byte X-coordinate.
  • py 32-byte Y-coordinate.

Returns:

true if point is on curve, false otherwise.


function syn_p256_point_mul

Multiply an arbitrary P-256 point by a 32-byte scalar.

bool syn_p256_point_mul (
    const uint8_t scalar,
    const uint8_t px,
    const uint8_t py,
    uint8_t rx,
    uint8_t ry
) 

Computes R = scalar * P.

Parameters:

  • scalar 32-byte scalar in big-endian format.
  • px 32-byte X-coordinate of input point P.
  • py 32-byte Y-coordinate of input point P.
  • rx [out] 32-byte X-coordinate of resulting point R.
  • ry [out] 32-byte Y-coordinate of resulting point R.

Returns:

true on success, false if point is invalid or scalar out of range.


function syn_p256_sign_ecdsa

Generate a NIST P-256 ECDSA signature (FIPS 186-4).

bool syn_p256_sign_ecdsa (
    const uint8_t priv_key,
    const uint8_t nonce_k,
    const uint8_t hash,
    uint8_t r_out,
    uint8_t s_out
) 

Computes signature (r, s) for a given message hash using a private key and nonce k.

Parameters:

  • priv_key 32-byte private key scalar.
  • nonce_k 32-byte ephemeral private nonce k (must be in [1, n-1]).
  • hash 32-byte message hash (typically SHA-256).
  • r_out [out] 32-byte signature component r.
  • s_out [out] 32-byte signature component s.

Returns:

true on success, false on invalid parameters.


function syn_p256_sign_ecdsa_deterministic

Generate a deterministic NIST P-256 ECDSA signature (RFC 6979 / FIPS 186-4).

bool syn_p256_sign_ecdsa_deterministic (
    const uint8_t priv_key,
    const uint8_t hash,
    uint8_t r_out,
    uint8_t s_out
) 

Derives the ephemeral nonce k deterministically using NIST SP 800-90A HMAC-DRBG (SHA-256) keyed with the private key and message hash.

Parameters:

  • priv_key 32-byte private key scalar.
  • hash 32-byte message hash (typically SHA-256).
  • r_out [out] 32-byte signature component r.
  • s_out [out] 32-byte signature component s.

Returns:

true on success, false on invalid parameters.


function syn_p256_verify_ecdsa

Verify a NIST P-256 ECDSA signature (FIPS 186-4).

bool syn_p256_verify_ecdsa (
    const uint8_t hash,
    const uint8_t r,
    const uint8_t s,
    const uint8_t pub_x,
    const uint8_t pub_y
) 

Parameters:

  • hash 32-byte message hash (typically SHA-256).
  • r 32-byte signature component r.
  • s 32-byte signature component s.
  • pub_x 32-byte public key X-coordinate.
  • pub_y 32-byte public key Y-coordinate.

Returns:

true if signature is mathematically valid, false otherwise.


Public Static Functions Documentation

function bn_add_raw

Raw 256-bit addition with carry out.

static uint32_t bn_add_raw (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Sum result.
  • a First term.
  • b Second term.

Returns:

Carry out bit (0 or 1).


function bn_cmp

Compare two 256-bit big numbers.

static int bn_cmp (
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • a First big number.
  • b Second big number.

Returns:

1 if a > b, -1 if a < b, 0 if equal.


function bn_copy

Copy bignum256.

static void bn_copy (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Destination.
  • a Source.

function bn_div2_mod_n

Halving modulo n: computes (a / 2) mod n.

static void bn_div2_mod_n (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Result.
  • a Input bignum.

function bn_from_bytes

Load bignum256 from 32 big-endian bytes.

static void bn_from_bytes (
    bignum256 r,
    const uint8_t bytes
) 

Parameters:

  • r Output big-number.
  • bytes 32-byte big-endian input array.

function bn_is_zero

Check if bignum256 is zero.

static bool bn_is_zero (
    const bignum256 a
) 

Parameters:

  • a Input big number.

Returns:

True if zero, false otherwise.


function bn_mul_raw

256x256-bit raw integer multiplication producing a 512-bit product.

static void bn_mul_raw (
    uint32_t t,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • t 512-bit product (16 limbs).
  • a First 256-bit factor.
  • b Second 256-bit factor.

function bn_rshift1

Shift 256-bit bignum right by 1 bit.

static void bn_rshift1 (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Result.
  • a Input bignum.

function bn_sub_raw

Raw 256-bit subtraction with borrow out.

static uint32_t bn_sub_raw (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Difference result.
  • a Minuend.
  • b Subtrahend.

Returns:

Borrow out bit (0 or 1).


function bn_to_bytes

Export bignum256 to 32 big-endian bytes.

static void bn_to_bytes (
    uint8_t bytes,
    const bignum256 a
) 

Parameters:

  • bytes 32-byte big-endian output array.
  • a Input big-number.

function p256_mod_n_inv

Group order inversion modulo n via Binary Extended Euclidean Algorithm: a^(-1) mod n.

static void p256_mod_n_inv (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Inverted value.
  • a Base to invert.

function p256_mod_n_mul

Group order multiplication modulo n.

static void p256_mod_n_mul (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Product modulo n.
  • a First factor.
  • b Second factor.

function p256_mod_n_sub

Subtraction modulo n.

static void p256_mod_n_sub (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Difference mod n.
  • a Minuend.
  • b Subtrahend.

function p256_mod_p_add

Field addition modulo p.

static void p256_mod_p_add (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Sum modulo p.
  • a First operand.
  • b Second operand.

function p256_mod_p_inv

Field inversion modulo p via Fermat's Little Theorem: a^(p-2) mod p.

static void p256_mod_p_inv (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Inverted value.
  • a Base to invert.

function p256_mod_p_mul

Field multiplication modulo p.

static void p256_mod_p_mul (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Product modulo p.
  • a First factor.
  • b Second factor.

function p256_mod_p_reduce

512-bit integer fast reduction modulo p using Solinas algorithm for NIST P-256.

static void p256_mod_p_reduce (
    bignum256 r,
    const uint32_t c
) 

Parameters:

  • r Reduced 256-bit value modulo p.
  • c 512-bit integer in 16 32-bit limbs.

function p256_mod_p_sqr

Field squaring modulo p.

static void p256_mod_p_sqr (
    bignum256 r,
    const bignum256 a
) 

Parameters:

  • r Result a^2 mod p.
  • a Base.

function p256_mod_p_sub

Field subtraction modulo p.

static void p256_mod_p_sub (
    bignum256 r,
    const bignum256 a,
    const bignum256 b
) 

Parameters:

  • r Difference modulo p.
  • a Minuend.
  • b Subtrahend.

function point_add

Point Addition in Jacobian coordinates: P + Q.

static void point_add (
    P256_Point * r,
    const P256_Point * p,
    const P256_Point * q
) 

Parameters:

  • r Output point P + Q.
  • p First Jacobian point.
  • q Second Jacobian point.

function point_add_mixed

Mixed Jacobian + Affine Addition: P (Jacobian) + Q (Affine).

static void point_add_mixed (
    P256_Point * r,
    const P256_Point * p,
    const bignum256 qx,
    const bignum256 qy
) 

Parameters:

  • r Output point P + Q.
  • p Input Jacobian point.
  • qx Input Affine point X coordinate.
  • qy Input Affine point Y coordinate.

function point_cmov

Constant-time conditional point move: dst = (mask != 0) ? src : dst.

static void point_cmov (
    P256_Point * dst,
    const P256_Point * src,
    uint32_t mask
) 

Parameters:

  • dst Destination point.
  • src Source point.
  • mask Bitmask (0x00000000 or 0xFFFFFFFF).

function point_double

Point Doubling in Jacobian coordinates: 2P.

static void point_double (
    P256_Point * r,
    const P256_Point * p
) 

Parameters:

  • r Output point 2P.
  • p Input point P.

function point_scalar_mul_affine

Constant-time Windowed Scalar Multiplication: k * P (where P is affine (px, py)).

static void point_scalar_mul_affine (
    P256_Point * r,
    const bignum256 k,
    const bignum256 px,
    const bignum256 py
) 

Parameters:

  • r Output Jacobian point.
  • k Scalar factor.
  • px Affine base point X coordinate.
  • py Affine base point Y coordinate.

function point_set_infinity

Set Jacobian point to infinity.

static void point_set_infinity (
    P256_Point * p
) 

Parameters:

  • p Point structure to initialize to infinity.

function point_to_affine

Convert Jacobian coordinates (X, Y, Z) to Affine coordinates (x, y).

static void point_to_affine (
    const P256_Point * p,
    bignum256 x_out,
    bignum256 y_out
) 

Parameters:

  • p Input Jacobian point.
  • x_out Output affine X coordinate.
  • y_out Output affine Y coordinate.


The documentation for this class was generated from the following file src/syntropic/crypto/syn_p256.c