UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
types.hpp
Go to the documentation of this file.
1// =============================================================================
2// UltrafastSecp256k1 -- Shared POD Data Types
3// =============================================================================
4// Canonical data layouts for secp256k1 field elements, scalars, and points.
5// These types define the MEMORY LAYOUT contract between all backends
6// (CPU, CUDA, OpenCL). Each backend may extend with its own methods,
7// alignment, or __device__ qualifiers, but must remain layout-compatible.
8//
9// Design principles:
10// - Pure POD: no constructors, no virtual methods, no inheritance
11// - Zero overhead: reinterpret_cast between backend and shared types
12// - Little-endian limbs: limbs[0] is the least significant
13//
14// Backend usage:
15// - CUDA: using FieldElement = secp256k1::FieldElementData; (direct alias)
16// - OpenCL: struct FieldElement { ... }; + static_assert layout match
17// - CPU: class FieldElement { ... }; + data()/from_data() accessors
18// =============================================================================
19
20#pragma once
21
22#include <cstdint>
23#include <cstddef>
24
25namespace secp256k1 {
26
27// -----------------------------------------------------------------------------
28// Field element: 256-bit integer mod p (secp256k1 prime)
29// p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
30// -----------------------------------------------------------------------------
32 uint64_t limbs[4]; // Little-endian: limbs[0] = bits [0..63]
33};
34
35// -----------------------------------------------------------------------------
36// 32-bit view of field element (same 256 bits, different interpretation)
37// Memory layout is IDENTICAL to FieldElementData -- safe to reinterpret_cast
38// -----------------------------------------------------------------------------
40 uint32_t limbs[8]; // Little-endian: limbs[0] = bits [0..31]
41};
42
43// -----------------------------------------------------------------------------
44// Scalar: 256-bit integer mod n (curve order)
45// n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
46// -----------------------------------------------------------------------------
47struct ScalarData {
48 uint64_t limbs[4]; // Little-endian: limbs[0] = bits [0..63]
49};
50
51// -----------------------------------------------------------------------------
52// Affine point: (x, y) on the curve y^2 = x^3 + 7
53// -----------------------------------------------------------------------------
58
59// -----------------------------------------------------------------------------
60// Jacobian point: (X, Y, Z) where affine (x, y) = (X/Z^2, Y/Z^3)
61//
62// NOTE: The infinity flag representation varies by backend:
63// - CPU: bool (1 byte) -- inside Point class
64// - CUDA: bool (1 byte) -- in JacobianPoint struct
65// - OpenCL: uint32_t (4 bytes, GPU-friendly with padding)
66//
67// This reference layout uses uint32_t for maximum portability.
68// Backends may define their own JacobianPoint with a different infinity type
69// as long as the x/y/z field offsets match.
70// -----------------------------------------------------------------------------
75 uint32_t infinity; // 1 = point at infinity, 0 = normal point
76};
77
78// =============================================================================
79// Layout Guarantees
80// =============================================================================
81static_assert(sizeof(FieldElementData) == 32, "FieldElement must be 256 bits");
82static_assert(sizeof(MidFieldElementData) == 32, "MidFieldElement must be 256 bits");
83static_assert(sizeof(ScalarData) == 32, "Scalar must be 256 bits");
84static_assert(sizeof(AffinePointData) == 64, "AffinePoint must be 512 bits");
85
86// FieldElementData and MidFieldElementData are reinterpret_cast-compatible
87static_assert(sizeof(FieldElementData) == sizeof(MidFieldElementData),
88 "FieldElementData and MidFieldElementData must be same size");
89
90// Field offsets for cross-backend compatibility checks
91static_assert(offsetof(AffinePointData, x) == 0, "AffinePoint.x at offset 0");
92static_assert(offsetof(AffinePointData, y) == 32, "AffinePoint.y at offset 32");
93
94static_assert(offsetof(JacobianPointData, x) == 0, "JacobianPoint.x at offset 0");
95static_assert(offsetof(JacobianPointData, y) == 32, "JacobianPoint.y at offset 32");
96static_assert(offsetof(JacobianPointData, z) == 64, "JacobianPoint.z at offset 64");
97
98// =============================================================================
99// Zero-cost Conversion Utilities
100// =============================================================================
101// These are provided for convenience in wrapper/bridge code.
102// Within each backend, prefer using the backend's native type directly.
103
104inline FieldElementData* fe_to_data(void* fe) noexcept {
105 return static_cast<FieldElementData*>(fe);
106}
107
108inline const FieldElementData* fe_to_data(const void* fe) noexcept {
109 return static_cast<const FieldElementData*>(fe);
110}
111
112inline ScalarData* sc_to_data(void* sc) noexcept {
113 return static_cast<ScalarData*>(sc);
114}
115
116inline const ScalarData* sc_to_data(const void* sc) noexcept {
117 return static_cast<const ScalarData*>(sc);
118}
119
120} // namespace secp256k1
FieldElementData * fe_to_data(void *fe) noexcept
Definition types.hpp:104
ScalarData * sc_to_data(void *sc) noexcept
Definition types.hpp:112
FieldElementData x
Definition types.hpp:55
FieldElementData y
Definition types.hpp:56
FieldElementData z
Definition types.hpp:74
FieldElementData x
Definition types.hpp:72
FieldElementData y
Definition types.hpp:73
uint64_t limbs[4]
Definition types.hpp:48