Expand description
Scalar reduction, multiplication, and multiply-add datapaths.
§Scalar Arithmetic Modules
Ed25519 scalars are reduced modulo
l = 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed. The active datapath uses
fully spatial radix-2^16 products and fixed-depth carry pipelines. It accepts
new work every cycle and avoids the 512-step bit-serial reduction retained in
scalar_arithmetic_2phase.sv.
§radix16_const_q_mul_pipe
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_dsp_pipe.sv.
This reusable pipeline multiplies a variable radix-2^16 integer by the fixed
128-bit constant q = l - 2^252. It also delays arbitrary sideband metadata by
the same number of cycles.
§Parameters
| Parameter | Default | Meaning |
|---|---|---|
XLIMBS | 17 | Number of 16-bit limbs in input x; active reducer stages override it with 17, 9, and 5 |
SIDE_BITS | 1 | Width of metadata carried unchanged from side_in to side_out |
CONST_Q | Ed25519 q | Eight 16-bit limbs of the fixed multiplier constant |
Internal derived parameters are COEFFS = XLIMBS + 7, CHUNKS = COEFFS/2,
LATENCY = 5 + CHUNKS, and PAD_LIMBS = XLIMBS + 14. An initial assertion
requires COEFFS to be divisible by two, because each normalization stage
handles exactly two coefficients. START = chunk*2 is the first coefficient
handled by one generated normalization stage.
§Ports
| Port | Direction | Meaning |
|---|---|---|
clk, rst | input | Clock and synchronous valid-pipeline reset |
valid_in | input | Qualifies x and side_in; initiation interval is one |
x | input, XLIMBS*16 bits | Little-endian radix-2^16 multiplicand |
side_in | input, SIDE_BITS | Opaque metadata aligned with x |
valid_out | output | Qualifies product and side_out |
product | output, (XLIMBS+8)*16 bits | Normalized little-endian product including final carry limb |
side_out | output, SIDE_BITS | Delayed copy of side_in |
The pipeline is fully spatial and initiation-interval one:
| Stage | Function |
|---|---|
| 1 | Register the eight variable 16-bit limbs contributing to each output coefficient |
| 2 | Multiply those limbs by the eight fixed limbs of q |
| 3 | Reduce eight products to four pair sums |
| 4 | Reduce four pairs to two quad sums |
| 5 | Add the two quads into one unnormalized convolution coefficient |
6..5+CHUNKS | Normalize two adjacent radix-2^16 coefficients per stage and forward the carry |
Static zero padding makes every part select legal and lets Vivado remove products whose variable operand limb is known to be zero. Active fold sizes therefore have these exact valid-pipeline lengths:
XLIMBS | COEFFS | Normalization stages | Total latency positions |
|---|---|---|---|
| 17 | 24 | 12 | 17 |
| 9 | 16 | 8 | 13 |
| 5 | 12 | 6 | 11 |
§scalar_reduce_wide_dsp_pipe
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_dsp_pipe.sv.
This is the active 512-bit reduction pipeline. The signing core has separate
instances for nonce r and challenge k; scalar_muladd_dsp_pipe contains a
third instance for the final result.
§Parameter
| Parameter | Default | Meaning |
|---|---|---|
TAG_BITS | 8 | Width of the context metadata delayed with the scalar |
Its local constants are L, the 253-bit group order, and TWO_L, a positive
bias used before final subtraction.
§Ports
| Port | Direction | Meaning |
|---|---|---|
clk, rst | input | Clock and synchronous valid reset |
valid_in | input | Qualifies wide_in and tag_in |
wide_in | input, 512 bits | Little-endian integer to reduce |
tag_in | input, TAG_BITS | Context identifier or other metadata |
valid_out | output | Qualifies the canonical result |
scalar_out | output, 256 bits | Canonical scalar in bits 252:0 with three high zero bits |
tag_out | output, TAG_BITS | Delayed input tag |
The reduction uses l = 2^252 + q, hence 2^252 = -q mod l:
- Split
x = x0 + 2^252*x1and compute the first fixed productq*x1withXLIMBS=17. - Fold the high part of that product with a second
qmultiplication usingXLIMBS=9. - Fold the remaining small carry with
XLIMBS=5. - Form separate positive and negative sums, add
2*las a nonnegative bias, and perform three registered conditional subtractions ofl.
The final section occupies five registered positions: positive/negative sums, biased subtraction, and three successive conditional reductions. With the 17-, 13-, and 11-position fixed-product folds, the complete reducer has 46 valid-pipeline positions and initiation interval one.
The schedule and number of operations are independent of scalar bits. The current matching-source U280 hierarchy uses 626 DSP48E2s per reducer.
§radix16_wide_mul_pipe
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_dsp_pipe.sv.
This pipeline forms a full 256x256-bit product from sixteen 16-bit limbs per operand. Coefficient 31 is an intentional zero/carry pad so sixteen identical two-coefficient carry stages can normalize the result.
§Parameter
| Parameter | Default | Meaning |
|---|---|---|
SIDE_BITS | 1 | Width of metadata delayed beside the product |
Local parameters are COEFFS=32, CHUNKS=16, LATENCY=6+CHUNKS=22, and
generated START=chunk*2 offsets for the carry chunks.
§Ports
| Port | Direction | Meaning |
|---|---|---|
clk, rst | input | Clock and synchronous valid reset |
valid_in | input | Qualifies both operands and metadata |
x, y | input, 256 bits each | Little-endian integers |
side_in | input, SIDE_BITS | Metadata to retain |
valid_out | output | Product validity |
product | output, 528 bits | Full normalized product plus guard carry |
side_out | output, SIDE_BITS | Delayed metadata |
The 22 positions are one input-limb register, one 16x16 product stage, pair, quad, octet, and full-coefficient adder stages, followed by sixteen stages that normalize two radix-16 limbs each. The integrated multiply-add hierarchy attributes 338 DSP48E2s to this multiplier after static-zero removal and DSP mapping of registered additions.
§scalar_muladd_dsp_pipe
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_dsp_pipe.sv.
This active module computes (a_in * b_in + c_in) mod l, which the signer uses
as S = k*a + r mod l.
§Parameter
| Parameter | Default | Meaning |
|---|---|---|
TAG_BITS | 8 | Metadata width retained through multiplication, addition, and reduction |
§Ports
| Port | Direction | Meaning |
|---|---|---|
clk, rst | input | Clock and synchronous valid reset |
valid_in | input | Qualifies a_in, b_in, c_in, and tag_in |
a_in, b_in | input, 256 bits | Multiplicands; the signer supplies secret a and challenge k |
c_in | input, 256 bits | Addend; the signer supplies nonce r |
tag_in | input, TAG_BITS | Signing context |
valid_out | output | Qualifies scalar_out and tag_out |
scalar_out | output, 256 bits | Canonical modular multiply-add result |
tag_out | output, TAG_BITS | Delayed context |
radix16_wide_mul_pipe forms a*b while carrying {tag,c} as sideband data.
One registered CLB carry-chain stage adds c to the low 512 product bits. A
scalar_reduce_wide_dsp_pipe then canonicalizes the sum. The data path contains
22 wide-multiply positions, one addition position, and the 46-position reducer,
for 69 registered valid positions and initiation interval one.
Current matching-source OOC hierarchy attribution is 338 DSPs in the wide multiplier, 626 in the nested reducer, and 273 mapped to accumulation and normalization logic owned at the multiply-add hierarchy boundary, for 1,237 DSP48E2s total. Treat those figures as synthesis attribution; hierarchy optimization can move arithmetic primitives across source-module boundaries.
§scalar_signing_cluster_dsp
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_dsp_pipe.sv.
This module is an OOC synthesis probe, not an instantiated child of the cached signer. It groups the same three scalar services so a focused build can report their combined area.
§Parameter
TAG_BITS defaults to 8 and sets every nonce, challenge, and multiply-add tag
width.
§Ports
| Prefix | Inputs | Outputs | Function |
|---|---|---|---|
nonce_ | nonce_valid_in, nonce_wide_in, nonce_tag_in | nonce_valid_out, nonce_scalar_out, nonce_tag_out | One scalar_reduce_wide_dsp_pipe |
challenge_ | challenge_valid_in, challenge_wide_in, challenge_tag_in | challenge_valid_out, challenge_scalar_out, challenge_tag_out | A second independent reducer |
muladd_ | muladd_valid_in, muladd_a_in, muladd_b_in, muladd_c_in, muladd_tag_in | muladd_valid_out, muladd_scalar_out, muladd_tag_out | One scalar_muladd_dsp_pipe |
All three groups share clk and rst but otherwise operate independently.
§Legacy scalar_reduce_wide_2phase
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_2phase.sv.
This parameterless predecessor scans all 512 input bits with a shift-and-
conditional-subtract reducer. Ports are clk, rst, start, ready,
wide_in, valid_out, and scalar_out. ready is high only in ST_IDLE.
ST_CALC computes one shifted remainder and optional subtraction of local
constant L; ST_COMMIT stores it, shifts the next input bit into position,
and either loops or pulses the canonical output. Its work is fixed but takes
roughly two cycles per input bit.
§Legacy scalar_muladd_2phase
Source: crates/rhdl_ed25519_fast_scalar/rtl/scalar_arithmetic_2phase.sv.
This parameterless predecessor computes (a_in*b_in+c_in) mod l with serial
double-and-add. Ports are clk, rst, start, ready, three 256-bit inputs
a_in, b_in, c_in, and outputs valid_out, scalar_out.
Its local states are ST_IDLE, ST_NORM_CALC, ST_NORM_COMMIT,
ST_MUL_CALC, and ST_MUL_COMMIT. Eight normalization iterations repeatedly
subtract L from a_in if needed. It then visits all 256 multiplier bits,
conditionally adds the current addend, doubles that addend, and reduces both
operations modulo L. This file is still passed to some build scripts but its
modules are not instantiated by the active cached core.