diff --git a/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr b/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
index 5adc82bb..e9a635f1 100644
--- a/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
+++ b/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
@@ -209,8 +209,11 @@ uses
ClpChaChaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaX86Backend.pas',
ClpChaChaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaArmBackend.pas',
ClpFpKernelSimd in '..\..\CryptoLib\src\Simd\Facade\ClpFpKernelSimd.pas',
+ ClpCurveFieldSimd in '..\..\CryptoLib\src\Simd\Facade\ClpCurveFieldSimd.pas',
ClpFpKernelX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelX86Backend.pas',
+ ClpCurveFieldX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldX86Backend.pas',
ClpFpKernelArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelArmBackend.pas',
+ ClpCurveFieldArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldArmBackend.pas',
ClpSalsaSimd in '..\..\CryptoLib\src\Simd\Facade\ClpSalsaSimd.pas',
ClpSalsaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaX86Backend.pas',
ClpSalsaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaArmBackend.pas',
diff --git a/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr b/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
index 812cb6ff..7115d277 100644
--- a/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
+++ b/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
@@ -228,8 +228,11 @@ uses
ClpChaChaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaX86Backend.pas',
ClpChaChaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaArmBackend.pas',
ClpFpKernelSimd in '..\..\CryptoLib\src\Simd\Facade\ClpFpKernelSimd.pas',
+ ClpCurveFieldSimd in '..\..\CryptoLib\src\Simd\Facade\ClpCurveFieldSimd.pas',
ClpFpKernelX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelX86Backend.pas',
+ ClpCurveFieldX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldX86Backend.pas',
ClpFpKernelArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelArmBackend.pas',
+ ClpCurveFieldArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldArmBackend.pas',
ClpSalsaSimd in '..\..\CryptoLib\src\Simd\Facade\ClpSalsaSimd.pas',
ClpSalsaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaX86Backend.pas',
ClpSalsaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaArmBackend.pas',
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
index 10ea09b9..1873eecf 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
@@ -205,8 +205,11 @@ uses
ClpChaChaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaX86Backend.pas',
ClpChaChaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpChaChaArmBackend.pas',
ClpFpKernelSimd in '..\..\CryptoLib\src\Simd\Facade\ClpFpKernelSimd.pas',
+ ClpCurveFieldSimd in '..\..\CryptoLib\src\Simd\Facade\ClpCurveFieldSimd.pas',
ClpFpKernelX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelX86Backend.pas',
+ ClpCurveFieldX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldX86Backend.pas',
ClpFpKernelArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelArmBackend.pas',
+ ClpCurveFieldArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldArmBackend.pas',
ClpSalsaSimd in '..\..\CryptoLib\src\Simd\Facade\ClpSalsaSimd.pas',
ClpSalsaX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaX86Backend.pas',
ClpSalsaArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpSalsaArmBackend.pas',
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
index a2b8f40e..122bb547 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
@@ -548,8 +548,11 @@
+
+
+
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
index 3a7b4312..d3770b3e 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
@@ -412,8 +412,11 @@ uses
ClpFpCTMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFpCTMultiplier.pas',
ClpFpCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFpCombMultiplier.pas',
ClpFpKernelSimd in '..\..\CryptoLib\src\Simd\Facade\ClpFpKernelSimd.pas',
+ ClpCurveFieldSimd in '..\..\CryptoLib\src\Simd\Facade\ClpCurveFieldSimd.pas',
ClpFpKernelX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelX86Backend.pas',
+ ClpCurveFieldX86Backend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldX86Backend.pas',
ClpFpKernelArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpFpKernelArmBackend.pas',
+ ClpCurveFieldArmBackend in '..\..\CryptoLib\src\Simd\Backend\ClpCurveFieldArmBackend.pas',
ClpIF2mFieldOps in '..\..\CryptoLib\src\Interfaces\Math\EC\Multiplier\ClpIF2mFieldOps.pas',
ClpLopezDahabLadder in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpLopezDahabLadder.pas',
ClpF2mMontgomeryLadderCTMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpF2mMontgomeryLadderCTMultiplier.pas',
diff --git a/CryptoLib/src/Include/CryptoLibFPC.inc b/CryptoLib/src/Include/CryptoLibFPC.inc
index 105198f4..6a1041b7 100644
--- a/CryptoLib/src/Include/CryptoLibFPC.inc
+++ b/CryptoLib/src/Include/CryptoLibFPC.inc
@@ -144,7 +144,6 @@
{$ASMMODE STANDARD}
{$IFEND}
-{$OPTIMIZATION NOREGVAR}
(*
{$OPTIMIZATION LEVEL3}
{$OPTIMIZATION NOREGVAR}
diff --git a/CryptoLib/src/Include/Simd/Curve25519/X25519Field_aarch64.inc b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_aarch64.inc
new file mode 100644
index 00000000..cefb4d10
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_aarch64.inc
@@ -0,0 +1,1175 @@
+// Curve25519 field kernels (AArch64), radix-2^25.5, ten signed Int32 limbs.
+// One selector-driven file; define exactly one of the following before the
+// include (each pairs with its ClpSimdProcBegin prologue):
+//
+// CRYPTOLIB_CURVE25519_MUL (Proc3: x0=PF, x1=PG, x2=PH)
+// PH := PF * PG
+// CRYPTOLIB_CURVE25519_SQR (Proc2: x0=PX, x1=PZ)
+// PZ := PX^2
+// CRYPTOLIB_CURVE25519_ADD (Proc3: x0=PX, x1=PY, x2=PZ)
+// PZ := PX + PY
+// CRYPTOLIB_CURVE25519_SUB (Proc3: x0=PX, x1=PY, x2=PZ)
+// PZ := PX - PY
+// CRYPTOLIB_CURVE25519_APM (Proc4: x0=PX, x1=PY, x2=PZp, x3=PZm)
+// PZp := PX+PY; PZm := PX-PY
+// CRYPTOLIB_CURVE25519_CSWAP (Proc3: x0=ASwap, x1=PA, x2=PB)
+// constant-time swap of PA, PB
+// CRYPTOLIB_CURVE25519_CARRY (Proc1: x0=PZ)
+// carry-propagate (reduce) PZ in place
+// CRYPTOLIB_CURVE25519_MULWORD (Proc3: x0=PX, x1=AY, x2=PZ)
+// PZ := PX * AY (small scalar AY)
+//
+// Register-resident: Mul/Sqr keep the ten columns in x3..x12 (smull with a
+// per-column x19 fold); Carry stays in registers. All results mod 2^255-19;
+// signed limbs => smull only. Constant-time; x0..x17 only, no prolog spill.
+{$IFDEF CRYPTOLIB_CURVE25519_MUL}
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x3, x15, #2
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #1
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #2
+ lsl x16, x3, #4
+ add x16, x16, x3, lsl #1
+ add x3, x16, x3
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x3, x3, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x4, x15, #2
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #1
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #2
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #1
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #1
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #2
+ lsl x16, x4, #4
+ add x16, x16, x4, lsl #1
+ add x4, x16, x4
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x4, x4, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x4, x4, x15
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x5, x15, #1
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ lsl x16, x5, #4
+ add x16, x16, x5, lsl #1
+ add x5, x16, x5
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x5, x5, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x5, x5, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x5, x5, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x6, x15, #2
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #1
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #2
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #2
+ lsl x16, x6, #4
+ add x16, x16, x6, lsl #1
+ add x6, x16, x6
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x6, x6, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x6, x6, x15
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x7, x15, #1
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ lsl x16, x7, #4
+ add x16, x16, x7, lsl #1
+ add x7, x16, x7
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x7, x7, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x7, x7, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x7, x7, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x7, x7, x15
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x8, x15, #2
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #2
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #2
+ lsl x16, x8, #4
+ add x16, x16, x8, lsl #1
+ add x8, x16, x8
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x8, x8, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #1
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #1
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x8, x8, x15
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x9, x15, #2
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #2
+ lsl x16, x9, #4
+ add x16, x16, x9, lsl #1
+ add x9, x16, x9
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x10, x15, #1
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x10, x10, x15, lsl #1
+ lsl x16, x10, #4
+ add x16, x16, x10, lsl #1
+ add x10, x16, x10
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x10, x10, x15
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ lsl x11, x15, #2
+ lsl x16, x11, #4
+ add x16, x16, x11, lsl #1
+ add x11, x16, x11
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x11, x11, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x11, x11, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x11, x11, x15
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x11, x11, x15
+ ldr w13, [x0, #0]
+ ldr w14, [x1, #36]
+ smull x15, w13, w14
+ mov x12, x15
+ ldr w13, [x0, #4]
+ ldr w14, [x1, #32]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x1, #28]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x1, #24]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x1, #20]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #20]
+ ldr w14, [x1, #16]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #24]
+ ldr w14, [x1, #12]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #28]
+ ldr w14, [x1, #8]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #1
+ ldr w13, [x0, #32]
+ ldr w14, [x1, #4]
+ smull x15, w13, w14
+ add x12, x12, x15
+ ldr w13, [x0, #36]
+ ldr w14, [x1, #0]
+ smull x15, w13, w14
+ add x12, x12, x15
+ asr x16, x4, #26
+ add x5, x5, x16
+ and x4, x4, #0x3FFFFFF
+ asr x16, x6, #26
+ add x7, x7, x16
+ and x6, x6, #0x3FFFFFF
+ asr x16, x9, #26
+ add x10, x10, x16
+ and x9, x9, #0x3FFFFFF
+ asr x16, x11, #26
+ add x12, x12, x16
+ and x11, x11, #0x3FFFFFF
+ asr x16, x5, #25
+ add x6, x6, x16
+ and x5, x5, #0x1FFFFFF
+ asr x16, x7, #25
+ add x8, x8, x16
+ and x7, x7, #0x1FFFFFF
+ asr x16, x10, #25
+ add x11, x11, x16
+ and x10, x10, #0x1FFFFFF
+ asr x16, x12, #25
+ mov x17, #38
+ madd x3, x16, x17, x3
+ and x12, x12, #0x1FFFFFF
+ asr x16, x3, #26
+ add x4, x4, x16
+ and x3, x3, #0x3FFFFFF
+ asr x16, x8, #26
+ add x9, x9, x16
+ and x8, x8, #0x3FFFFFF
+ asr x16, x4, #26
+ add x5, x5, x16
+ and x4, x4, #0x3FFFFFF
+ asr x16, x6, #26
+ add x7, x7, x16
+ and x6, x6, #0x3FFFFFF
+ asr x16, x9, #26
+ add x10, x10, x16
+ and x9, x9, #0x3FFFFFF
+ asr x16, x11, #26
+ add x12, x12, x16
+ and x11, x11, #0x3FFFFFF
+ str w3, [x2, #0]
+ str w4, [x2, #4]
+ str w5, [x2, #8]
+ str w6, [x2, #12]
+ str w7, [x2, #16]
+ str w8, [x2, #20]
+ str w9, [x2, #24]
+ str w10, [x2, #28]
+ str w11, [x2, #32]
+ str w12, [x2, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SQR}
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x3, x15, #3
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #3
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #3
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #3
+ ldr w13, [x0, #20]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x3, x3, x15, lsl #1
+ lsl x16, x3, #4
+ add x16, x16, x3, lsl #1
+ add x3, x16, x3
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #0]
+ smull x15, w13, w14
+ add x3, x3, x15
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x4, x15, #3
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #2
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #3
+ ldr w13, [x0, #20]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #2
+ lsl x16, x4, #4
+ add x16, x16, x4, lsl #1
+ add x4, x16, x4
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #4]
+ smull x15, w13, w14
+ add x4, x4, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x5, x15, #2
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #2
+ ldr w13, [x0, #20]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #2
+ ldr w13, [x0, #24]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ lsl x16, x5, #4
+ add x16, x16, x5, lsl #1
+ add x5, x16, x5
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #8]
+ smull x15, w13, w14
+ add x5, x5, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #4]
+ smull x15, w13, w14
+ add x5, x5, x15
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x6, x15, #3
+ ldr w13, [x0, #20]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #2
+ ldr w13, [x0, #24]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #3
+ lsl x16, x6, #4
+ add x16, x16, x6, lsl #1
+ add x6, x16, x6
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #12]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #8]
+ smull x15, w13, w14
+ add x6, x6, x15, lsl #2
+ ldr w13, [x0, #20]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x7, x15, #2
+ ldr w13, [x0, #24]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #2
+ ldr w13, [x0, #28]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #2
+ lsl x16, x7, #4
+ add x16, x16, x7, lsl #1
+ add x7, x16, x7
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #16]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #12]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #8]
+ smull x15, w13, w14
+ add x7, x7, x15, lsl #1
+ ldr w13, [x0, #24]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x8, x15, #3
+ ldr w13, [x0, #28]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #3
+ lsl x16, x8, #4
+ add x16, x16, x8, lsl #1
+ add x8, x16, x8
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #16]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #2
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #12]
+ smull x15, w13, w14
+ add x8, x8, x15, lsl #2
+ ldr w13, [x0, #28]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x9, x15, #3
+ ldr w13, [x0, #32]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ lsl x16, x9, #4
+ add x16, x16, x9, lsl #1
+ add x9, x16, x9
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #16]
+ smull x15, w13, w14
+ add x9, x9, x15, lsl #2
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #12]
+ smull x15, w13, w14
+ add x9, x9, x15
+ ldr w13, [x0, #32]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x10, x15, #2
+ lsl x16, x10, #4
+ add x16, x16, x10, lsl #1
+ add x10, x16, x10
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x10, x10, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x10, x10, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x10, x10, x15, lsl #1
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #16]
+ smull x15, w13, w14
+ add x10, x10, x15, lsl #1
+ ldr w13, [x0, #36]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x11, x15, #2
+ lsl x16, x11, #4
+ add x16, x16, x11, lsl #1
+ add x11, x16, x11
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #2
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #2
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #16]
+ smull x15, w13, w14
+ add x11, x11, x15, lsl #1
+ ldr w13, [x0, #0]
+ ldr w14, [x0, #36]
+ smull x15, w13, w14
+ lsl x12, x15, #1
+ ldr w13, [x0, #4]
+ ldr w14, [x0, #32]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #1
+ ldr w13, [x0, #8]
+ ldr w14, [x0, #28]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #2
+ ldr w13, [x0, #12]
+ ldr w14, [x0, #24]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #1
+ ldr w13, [x0, #16]
+ ldr w14, [x0, #20]
+ smull x15, w13, w14
+ add x12, x12, x15, lsl #1
+ asr x16, x4, #26
+ add x5, x5, x16
+ and x4, x4, #0x3FFFFFF
+ asr x16, x6, #26
+ add x7, x7, x16
+ and x6, x6, #0x3FFFFFF
+ asr x16, x9, #26
+ add x10, x10, x16
+ and x9, x9, #0x3FFFFFF
+ asr x16, x11, #26
+ add x12, x12, x16
+ and x11, x11, #0x3FFFFFF
+ asr x16, x5, #25
+ add x6, x6, x16
+ and x5, x5, #0x1FFFFFF
+ asr x16, x7, #25
+ add x8, x8, x16
+ and x7, x7, #0x1FFFFFF
+ asr x16, x10, #25
+ add x11, x11, x16
+ and x10, x10, #0x1FFFFFF
+ asr x16, x12, #25
+ mov x17, #38
+ madd x3, x16, x17, x3
+ and x12, x12, #0x1FFFFFF
+ asr x16, x3, #26
+ add x4, x4, x16
+ and x3, x3, #0x3FFFFFF
+ asr x16, x8, #26
+ add x9, x9, x16
+ and x8, x8, #0x3FFFFFF
+ asr x16, x4, #26
+ add x5, x5, x16
+ and x4, x4, #0x3FFFFFF
+ asr x16, x6, #26
+ add x7, x7, x16
+ and x6, x6, #0x3FFFFFF
+ asr x16, x9, #26
+ add x10, x10, x16
+ and x9, x9, #0x3FFFFFF
+ asr x16, x11, #26
+ add x12, x12, x16
+ and x11, x11, #0x3FFFFFF
+ str w3, [x1, #0]
+ str w4, [x1, #4]
+ str w5, [x1, #8]
+ str w6, [x1, #12]
+ str w7, [x1, #16]
+ str w8, [x1, #20]
+ str w9, [x1, #24]
+ str w10, [x1, #28]
+ str w11, [x1, #32]
+ str w12, [x1, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_ADD}
+ ldr w3, [x0, #0]
+ ldr w4, [x1, #0]
+ add w3, w3, w4
+ str w3, [x2, #0]
+ ldr w3, [x0, #4]
+ ldr w4, [x1, #4]
+ add w3, w3, w4
+ str w3, [x2, #4]
+ ldr w3, [x0, #8]
+ ldr w4, [x1, #8]
+ add w3, w3, w4
+ str w3, [x2, #8]
+ ldr w3, [x0, #12]
+ ldr w4, [x1, #12]
+ add w3, w3, w4
+ str w3, [x2, #12]
+ ldr w3, [x0, #16]
+ ldr w4, [x1, #16]
+ add w3, w3, w4
+ str w3, [x2, #16]
+ ldr w3, [x0, #20]
+ ldr w4, [x1, #20]
+ add w3, w3, w4
+ str w3, [x2, #20]
+ ldr w3, [x0, #24]
+ ldr w4, [x1, #24]
+ add w3, w3, w4
+ str w3, [x2, #24]
+ ldr w3, [x0, #28]
+ ldr w4, [x1, #28]
+ add w3, w3, w4
+ str w3, [x2, #28]
+ ldr w3, [x0, #32]
+ ldr w4, [x1, #32]
+ add w3, w3, w4
+ str w3, [x2, #32]
+ ldr w3, [x0, #36]
+ ldr w4, [x1, #36]
+ add w3, w3, w4
+ str w3, [x2, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SUB}
+ ldr w3, [x0, #0]
+ ldr w4, [x1, #0]
+ sub w3, w3, w4
+ str w3, [x2, #0]
+ ldr w3, [x0, #4]
+ ldr w4, [x1, #4]
+ sub w3, w3, w4
+ str w3, [x2, #4]
+ ldr w3, [x0, #8]
+ ldr w4, [x1, #8]
+ sub w3, w3, w4
+ str w3, [x2, #8]
+ ldr w3, [x0, #12]
+ ldr w4, [x1, #12]
+ sub w3, w3, w4
+ str w3, [x2, #12]
+ ldr w3, [x0, #16]
+ ldr w4, [x1, #16]
+ sub w3, w3, w4
+ str w3, [x2, #16]
+ ldr w3, [x0, #20]
+ ldr w4, [x1, #20]
+ sub w3, w3, w4
+ str w3, [x2, #20]
+ ldr w3, [x0, #24]
+ ldr w4, [x1, #24]
+ sub w3, w3, w4
+ str w3, [x2, #24]
+ ldr w3, [x0, #28]
+ ldr w4, [x1, #28]
+ sub w3, w3, w4
+ str w3, [x2, #28]
+ ldr w3, [x0, #32]
+ ldr w4, [x1, #32]
+ sub w3, w3, w4
+ str w3, [x2, #32]
+ ldr w3, [x0, #36]
+ ldr w4, [x1, #36]
+ sub w3, w3, w4
+ str w3, [x2, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_APM}
+ ldr w4, [x0, #0]
+ ldr w5, [x1, #0]
+ add w6, w4, w5
+ str w6, [x2, #0]
+ sub w7, w4, w5
+ str w7, [x3, #0]
+ ldr w4, [x0, #4]
+ ldr w5, [x1, #4]
+ add w6, w4, w5
+ str w6, [x2, #4]
+ sub w7, w4, w5
+ str w7, [x3, #4]
+ ldr w4, [x0, #8]
+ ldr w5, [x1, #8]
+ add w6, w4, w5
+ str w6, [x2, #8]
+ sub w7, w4, w5
+ str w7, [x3, #8]
+ ldr w4, [x0, #12]
+ ldr w5, [x1, #12]
+ add w6, w4, w5
+ str w6, [x2, #12]
+ sub w7, w4, w5
+ str w7, [x3, #12]
+ ldr w4, [x0, #16]
+ ldr w5, [x1, #16]
+ add w6, w4, w5
+ str w6, [x2, #16]
+ sub w7, w4, w5
+ str w7, [x3, #16]
+ ldr w4, [x0, #20]
+ ldr w5, [x1, #20]
+ add w6, w4, w5
+ str w6, [x2, #20]
+ sub w7, w4, w5
+ str w7, [x3, #20]
+ ldr w4, [x0, #24]
+ ldr w5, [x1, #24]
+ add w6, w4, w5
+ str w6, [x2, #24]
+ sub w7, w4, w5
+ str w7, [x3, #24]
+ ldr w4, [x0, #28]
+ ldr w5, [x1, #28]
+ add w6, w4, w5
+ str w6, [x2, #28]
+ sub w7, w4, w5
+ str w7, [x3, #28]
+ ldr w4, [x0, #32]
+ ldr w5, [x1, #32]
+ add w6, w4, w5
+ str w6, [x2, #32]
+ sub w7, w4, w5
+ str w7, [x3, #32]
+ ldr w4, [x0, #36]
+ ldr w5, [x1, #36]
+ add w6, w4, w5
+ str w6, [x2, #36]
+ sub w7, w4, w5
+ str w7, [x3, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CSWAP}
+ neg w0, w0
+ ldr w4, [x1, #0]
+ ldr w5, [x2, #0]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #0]
+ str w5, [x2, #0]
+ ldr w4, [x1, #4]
+ ldr w5, [x2, #4]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #4]
+ str w5, [x2, #4]
+ ldr w4, [x1, #8]
+ ldr w5, [x2, #8]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #8]
+ str w5, [x2, #8]
+ ldr w4, [x1, #12]
+ ldr w5, [x2, #12]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #12]
+ str w5, [x2, #12]
+ ldr w4, [x1, #16]
+ ldr w5, [x2, #16]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #16]
+ str w5, [x2, #16]
+ ldr w4, [x1, #20]
+ ldr w5, [x2, #20]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #20]
+ str w5, [x2, #20]
+ ldr w4, [x1, #24]
+ ldr w5, [x2, #24]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #24]
+ str w5, [x2, #24]
+ ldr w4, [x1, #28]
+ ldr w5, [x2, #28]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #28]
+ str w5, [x2, #28]
+ ldr w4, [x1, #32]
+ ldr w5, [x2, #32]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #32]
+ str w5, [x2, #32]
+ ldr w4, [x1, #36]
+ ldr w5, [x2, #36]
+ eor w6, w4, w5
+ and w6, w6, w0
+ eor w4, w4, w6
+ eor w5, w5, w6
+ str w4, [x1, #36]
+ str w5, [x2, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CARRY}
+ ldr w1, [x0, #0]
+ ldr w2, [x0, #4]
+ ldr w3, [x0, #8]
+ ldr w4, [x0, #12]
+ ldr w5, [x0, #16]
+ ldr w6, [x0, #20]
+ ldr w7, [x0, #24]
+ ldr w8, [x0, #28]
+ ldr w9, [x0, #32]
+ ldr w10, [x0, #36]
+ asr w11, w2, #26
+ add w3, w3, w11
+ and w2, w2, #0x3FFFFFF
+ asr w11, w4, #26
+ add w5, w5, w11
+ and w4, w4, #0x3FFFFFF
+ asr w11, w7, #26
+ add w8, w8, w11
+ and w7, w7, #0x3FFFFFF
+ asr w11, w9, #26
+ add w10, w10, w11
+ and w9, w9, #0x3FFFFFF
+ asr w11, w3, #25
+ add w4, w4, w11
+ and w3, w3, #0x1FFFFFF
+ asr w11, w5, #25
+ add w6, w6, w11
+ and w5, w5, #0x1FFFFFF
+ asr w11, w8, #25
+ add w9, w9, w11
+ and w8, w8, #0x1FFFFFF
+ asr w11, w10, #25
+ mov w12, #38
+ madd w1, w11, w12, w1
+ and w10, w10, #0x1FFFFFF
+ asr w11, w1, #26
+ add w2, w2, w11
+ and w1, w1, #0x3FFFFFF
+ asr w11, w6, #26
+ add w7, w7, w11
+ and w6, w6, #0x3FFFFFF
+ asr w11, w2, #26
+ add w3, w3, w11
+ and w2, w2, #0x3FFFFFF
+ asr w11, w4, #26
+ add w5, w5, w11
+ and w4, w4, #0x3FFFFFF
+ asr w11, w7, #26
+ add w8, w8, w11
+ and w7, w7, #0x3FFFFFF
+ asr w11, w9, #26
+ add w10, w10, w11
+ and w9, w9, #0x3FFFFFF
+ str w1, [x0, #0]
+ str w2, [x0, #4]
+ str w3, [x0, #8]
+ str w4, [x0, #12]
+ str w5, [x0, #16]
+ str w6, [x0, #20]
+ str w7, [x0, #24]
+ str w8, [x0, #28]
+ str w9, [x0, #32]
+ str w10, [x0, #36]
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_MULWORD}
+ ldr w12, [x0, #8]
+ smull x3, w12, w1
+ and w7, w3, #0x1FFFFFF
+ asr x3, x3, #25
+ ldr w12, [x0, #16]
+ smull x4, w12, w1
+ and w8, w4, #0x1FFFFFF
+ asr x4, x4, #25
+ ldr w12, [x0, #28]
+ smull x5, w12, w1
+ and w9, w5, #0x1FFFFFF
+ asr x5, x5, #25
+ ldr w12, [x0, #36]
+ smull x6, w12, w1
+ and w10, w6, #0x1FFFFFF
+ asr x6, x6, #25
+ mov w13, #38
+ mul x6, x6, x13
+ ldr w12, [x0, #0]
+ smull x13, w12, w1
+ add x6, x6, x13
+ and w13, w6, #0x3FFFFFF
+ str w13, [x2, #0]
+ asr x6, x6, #26
+ ldr w12, [x0, #20]
+ smull x13, w12, w1
+ add x4, x4, x13
+ and w13, w4, #0x3FFFFFF
+ str w13, [x2, #20]
+ asr x4, x4, #26
+ ldr w12, [x0, #4]
+ smull x13, w12, w1
+ add x6, x6, x13
+ and w13, w6, #0x3FFFFFF
+ str w13, [x2, #4]
+ asr x6, x6, #26
+ ldr w12, [x0, #12]
+ smull x13, w12, w1
+ add x3, x3, x13
+ and w13, w3, #0x3FFFFFF
+ str w13, [x2, #12]
+ asr x3, x3, #26
+ ldr w12, [x0, #24]
+ smull x13, w12, w1
+ add x4, x4, x13
+ and w13, w4, #0x3FFFFFF
+ str w13, [x2, #24]
+ asr x4, x4, #26
+ ldr w12, [x0, #32]
+ smull x13, w12, w1
+ add x5, x5, x13
+ and w13, w5, #0x3FFFFFF
+ str w13, [x2, #32]
+ asr x5, x5, #26
+ add w13, w7, w6
+ str w13, [x2, #8]
+ add w13, w8, w3
+ str w13, [x2, #16]
+ add w13, w9, w4
+ str w13, [x2, #28]
+ add w13, w10, w5
+ str w13, [x2, #36]
+{$ELSE}
+{$FATAL Define one of CRYPTOLIB_CURVE25519_MUL/SQR/ADD/SUB/APM/CSWAP/CARRY/MULWORD}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
diff --git a/CryptoLib/src/Include/Simd/Curve25519/X25519Field_i386.inc b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_i386.inc
new file mode 100644
index 00000000..c0ddb939
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_i386.inc
@@ -0,0 +1,2064 @@
+// Curve25519 field kernels (i386), radix-2^25.5, ten signed Int32 limbs.
+// One selector-driven file; define exactly one of the following before the
+// include (each pairs with its ClpSimdProcBegin prologue):
+//
+// CRYPTOLIB_CURVE25519_MUL (Proc3: ebx=PF, esi=PG, edi=PH)
+// PH := PF * PG
+// CRYPTOLIB_CURVE25519_SQR (Proc2: ebx=PX, esi=PZ)
+// PZ := PX^2
+// CRYPTOLIB_CURVE25519_ADD (Proc3: ebx=PX, esi=PY, edi=PZ)
+// PZ := PX + PY
+// CRYPTOLIB_CURVE25519_SUB (Proc3: ebx=PX, esi=PY, edi=PZ)
+// PZ := PX - PY
+// CRYPTOLIB_CURVE25519_APM (Proc4: ebx=PX, esi=PY, edi=PZp, eax=PZm)
+// PZp := PX+PY; PZm := PX-PY
+// CRYPTOLIB_CURVE25519_CSWAP (Proc3: ebx=ASwap, esi=PA, edi=PB)
+// constant-time swap of PA, PB
+// CRYPTOLIB_CURVE25519_CARRY (Proc1: ebx=PZ)
+// carry-propagate (reduce) PZ in place
+// CRYPTOLIB_CURVE25519_MULWORD (Proc3: ebx=PX, esi=AY, edi=PZ)
+// PZ := PX * AY (small scalar AY)
+//
+// Register-starved: Mul uses one 64-bit accumulator (EBP:ECX) with a per-column
+// x19 fold and a 10x Int64 stack area; Sqr reuses the Mul body via X*X; Carry is
+// in-place. All results mod 2^255-19; signed limbs => imul only. Constant-time.
+{$IFDEF CRYPTOLIB_CURVE25519_MUL}
+ push ebp
+ sub esp, 80
+ mov eax, [ebx+4]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+32]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+12]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+8]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+4]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+0], ecx
+ mov [esp+4], ebp
+ mov eax, [ebx+8]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+8]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+8], ecx
+ mov [esp+12], ebp
+ mov eax, [ebx+12]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+8]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+16], ecx
+ mov [esp+20], ebp
+ mov eax, [ebx+16]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+24], ecx
+ mov [esp+28], ebp
+ mov eax, [ebx+20]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+32], ecx
+ mov [esp+36], ebp
+ mov eax, [ebx+24]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+32]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+40], ecx
+ mov [esp+44], ebp
+ mov eax, [ebx+28]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+48], ecx
+ mov [esp+52], ebp
+ mov eax, [ebx+32]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+28]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+8]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+56], ecx
+ mov [esp+60], ebp
+ mov eax, [ebx+36]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+32]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+64], ecx
+ mov [esp+68], ebp
+ mov eax, [ebx+0]
+ imul dword ptr [esi+36]
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+32]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+72], ecx
+ mov [esp+76], ebp
+ mov eax, [esp+8]
+ mov edx, [esp+12]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+16], eax
+ adc [esp+20], edx
+ and dword ptr [esp+8], $03FFFFFF
+ mov dword ptr [esp+12], 0
+ mov eax, [esp+24]
+ mov edx, [esp+28]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+32], eax
+ adc [esp+36], edx
+ and dword ptr [esp+24], $03FFFFFF
+ mov dword ptr [esp+28], 0
+ mov eax, [esp+48]
+ mov edx, [esp+52]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+56], eax
+ adc [esp+60], edx
+ and dword ptr [esp+48], $03FFFFFF
+ mov dword ptr [esp+52], 0
+ mov eax, [esp+64]
+ mov edx, [esp+68]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+72], eax
+ adc [esp+76], edx
+ and dword ptr [esp+64], $03FFFFFF
+ mov dword ptr [esp+68], 0
+ mov eax, [esp+16]
+ mov edx, [esp+20]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+24], eax
+ adc [esp+28], edx
+ and dword ptr [esp+16], $01FFFFFF
+ mov dword ptr [esp+20], 0
+ mov eax, [esp+32]
+ mov edx, [esp+36]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+40], eax
+ adc [esp+44], edx
+ and dword ptr [esp+32], $01FFFFFF
+ mov dword ptr [esp+36], 0
+ mov eax, [esp+56]
+ mov edx, [esp+60]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+64], eax
+ adc [esp+68], edx
+ and dword ptr [esp+56], $01FFFFFF
+ mov dword ptr [esp+60], 0
+ mov eax, [esp+72]
+ mov edx, [esp+76]
+ shrd eax, edx, 25
+ sar edx, 25
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebx, edx
+ shld edx, eax, 4
+ shl eax, 4
+ add eax, ecx
+ adc edx, ebx
+ shld ebx, ecx, 1
+ shl ecx, 1
+ add eax, ecx
+ adc edx, ebx
+ add [esp+0], eax
+ adc [esp+4], edx
+ and dword ptr [esp+72], $01FFFFFF
+ mov dword ptr [esp+76], 0
+ mov eax, [esp+0]
+ mov edx, [esp+4]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+8], eax
+ adc [esp+12], edx
+ and dword ptr [esp+0], $03FFFFFF
+ mov dword ptr [esp+4], 0
+ mov eax, [esp+40]
+ mov edx, [esp+44]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+48], eax
+ adc [esp+52], edx
+ and dword ptr [esp+40], $03FFFFFF
+ mov dword ptr [esp+44], 0
+ mov eax, [esp+8]
+ mov edx, [esp+12]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+16], eax
+ adc [esp+20], edx
+ and dword ptr [esp+8], $03FFFFFF
+ mov dword ptr [esp+12], 0
+ mov eax, [esp+24]
+ mov edx, [esp+28]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+32], eax
+ adc [esp+36], edx
+ and dword ptr [esp+24], $03FFFFFF
+ mov dword ptr [esp+28], 0
+ mov eax, [esp+48]
+ mov edx, [esp+52]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+56], eax
+ adc [esp+60], edx
+ and dword ptr [esp+48], $03FFFFFF
+ mov dword ptr [esp+52], 0
+ mov eax, [esp+64]
+ mov edx, [esp+68]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+72], eax
+ adc [esp+76], edx
+ and dword ptr [esp+64], $03FFFFFF
+ mov dword ptr [esp+68], 0
+ mov eax, [esp+0]
+ mov [edi+0], eax
+ mov eax, [esp+8]
+ mov [edi+4], eax
+ mov eax, [esp+16]
+ mov [edi+8], eax
+ mov eax, [esp+24]
+ mov [edi+12], eax
+ mov eax, [esp+32]
+ mov [edi+16], eax
+ mov eax, [esp+40]
+ mov [edi+20], eax
+ mov eax, [esp+48]
+ mov [edi+24], eax
+ mov eax, [esp+56]
+ mov [edi+28], eax
+ mov eax, [esp+64]
+ mov [edi+32], eax
+ mov eax, [esp+72]
+ mov [edi+36], eax
+ add esp, 80
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SQR}
+ push edi
+ mov edi, esi
+ mov esi, ebx
+ push ebp
+ sub esp, 80
+ mov eax, [ebx+4]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+32]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+12]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+8]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+4]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+0], ecx
+ mov [esp+4], ebp
+ mov eax, [ebx+8]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+8]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+8], ecx
+ mov [esp+12], ebp
+ mov eax, [ebx+12]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+8]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+16], ecx
+ mov [esp+20], ebp
+ mov eax, [ebx+16]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+16]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+24], ecx
+ mov [esp+28], ebp
+ mov eax, [ebx+20]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+20]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+32], ecx
+ mov [esp+36], ebp
+ mov eax, [ebx+24]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+32]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+24]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+12]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+40], ecx
+ mov [esp+44], ebp
+ mov eax, [ebx+28]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+28]
+ shld edx, eax, 2
+ shl eax, 2
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+48], ecx
+ mov [esp+52], ebp
+ mov eax, [ebx+32]
+ imul dword ptr [esi+36]
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+32]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+28]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+8]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+56], ecx
+ mov [esp+60], ebp
+ mov eax, [ebx+36]
+ imul dword ptr [esi+36]
+ shld edx, eax, 2
+ shl eax, 2
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, ecx
+ mov edx, ebp
+ shld ebp, ecx, 4
+ shl ecx, 4
+ add ecx, eax
+ adc ebp, edx
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+0]
+ imul dword ptr [esi+32]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+24]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+16]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+4]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+64], ecx
+ mov [esp+68], ebp
+ mov eax, [ebx+0]
+ imul dword ptr [esi+36]
+ mov ecx, eax
+ mov ebp, edx
+ mov eax, [ebx+4]
+ imul dword ptr [esi+32]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+8]
+ imul dword ptr [esi+28]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+12]
+ imul dword ptr [esi+24]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+16]
+ imul dword ptr [esi+20]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+20]
+ imul dword ptr [esi+16]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+24]
+ imul dword ptr [esi+12]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+28]
+ imul dword ptr [esi+8]
+ shld edx, eax, 1
+ shl eax, 1
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+32]
+ imul dword ptr [esi+4]
+ add ecx, eax
+ adc ebp, edx
+ mov eax, [ebx+36]
+ imul dword ptr [esi+0]
+ add ecx, eax
+ adc ebp, edx
+ mov [esp+72], ecx
+ mov [esp+76], ebp
+ mov eax, [esp+8]
+ mov edx, [esp+12]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+16], eax
+ adc [esp+20], edx
+ and dword ptr [esp+8], $03FFFFFF
+ mov dword ptr [esp+12], 0
+ mov eax, [esp+24]
+ mov edx, [esp+28]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+32], eax
+ adc [esp+36], edx
+ and dword ptr [esp+24], $03FFFFFF
+ mov dword ptr [esp+28], 0
+ mov eax, [esp+48]
+ mov edx, [esp+52]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+56], eax
+ adc [esp+60], edx
+ and dword ptr [esp+48], $03FFFFFF
+ mov dword ptr [esp+52], 0
+ mov eax, [esp+64]
+ mov edx, [esp+68]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+72], eax
+ adc [esp+76], edx
+ and dword ptr [esp+64], $03FFFFFF
+ mov dword ptr [esp+68], 0
+ mov eax, [esp+16]
+ mov edx, [esp+20]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+24], eax
+ adc [esp+28], edx
+ and dword ptr [esp+16], $01FFFFFF
+ mov dword ptr [esp+20], 0
+ mov eax, [esp+32]
+ mov edx, [esp+36]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+40], eax
+ adc [esp+44], edx
+ and dword ptr [esp+32], $01FFFFFF
+ mov dword ptr [esp+36], 0
+ mov eax, [esp+56]
+ mov edx, [esp+60]
+ shrd eax, edx, 25
+ sar edx, 25
+ add [esp+64], eax
+ adc [esp+68], edx
+ and dword ptr [esp+56], $01FFFFFF
+ mov dword ptr [esp+60], 0
+ mov eax, [esp+72]
+ mov edx, [esp+76]
+ shrd eax, edx, 25
+ sar edx, 25
+ shld edx, eax, 1
+ shl eax, 1
+ mov ecx, eax
+ mov ebx, edx
+ shld edx, eax, 4
+ shl eax, 4
+ add eax, ecx
+ adc edx, ebx
+ shld ebx, ecx, 1
+ shl ecx, 1
+ add eax, ecx
+ adc edx, ebx
+ add [esp+0], eax
+ adc [esp+4], edx
+ and dword ptr [esp+72], $01FFFFFF
+ mov dword ptr [esp+76], 0
+ mov eax, [esp+0]
+ mov edx, [esp+4]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+8], eax
+ adc [esp+12], edx
+ and dword ptr [esp+0], $03FFFFFF
+ mov dword ptr [esp+4], 0
+ mov eax, [esp+40]
+ mov edx, [esp+44]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+48], eax
+ adc [esp+52], edx
+ and dword ptr [esp+40], $03FFFFFF
+ mov dword ptr [esp+44], 0
+ mov eax, [esp+8]
+ mov edx, [esp+12]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+16], eax
+ adc [esp+20], edx
+ and dword ptr [esp+8], $03FFFFFF
+ mov dword ptr [esp+12], 0
+ mov eax, [esp+24]
+ mov edx, [esp+28]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+32], eax
+ adc [esp+36], edx
+ and dword ptr [esp+24], $03FFFFFF
+ mov dword ptr [esp+28], 0
+ mov eax, [esp+48]
+ mov edx, [esp+52]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+56], eax
+ adc [esp+60], edx
+ and dword ptr [esp+48], $03FFFFFF
+ mov dword ptr [esp+52], 0
+ mov eax, [esp+64]
+ mov edx, [esp+68]
+ shrd eax, edx, 26
+ sar edx, 26
+ add [esp+72], eax
+ adc [esp+76], edx
+ and dword ptr [esp+64], $03FFFFFF
+ mov dword ptr [esp+68], 0
+ mov eax, [esp+0]
+ mov [edi+0], eax
+ mov eax, [esp+8]
+ mov [edi+4], eax
+ mov eax, [esp+16]
+ mov [edi+8], eax
+ mov eax, [esp+24]
+ mov [edi+12], eax
+ mov eax, [esp+32]
+ mov [edi+16], eax
+ mov eax, [esp+40]
+ mov [edi+20], eax
+ mov eax, [esp+48]
+ mov [edi+24], eax
+ mov eax, [esp+56]
+ mov [edi+28], eax
+ mov eax, [esp+64]
+ mov [edi+32], eax
+ mov eax, [esp+72]
+ mov [edi+36], eax
+ add esp, 80
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_ADD}
+ mov eax, [ebx+0]
+ add eax, [esi+0]
+ mov [edi+0], eax
+ mov eax, [ebx+4]
+ add eax, [esi+4]
+ mov [edi+4], eax
+ mov eax, [ebx+8]
+ add eax, [esi+8]
+ mov [edi+8], eax
+ mov eax, [ebx+12]
+ add eax, [esi+12]
+ mov [edi+12], eax
+ mov eax, [ebx+16]
+ add eax, [esi+16]
+ mov [edi+16], eax
+ mov eax, [ebx+20]
+ add eax, [esi+20]
+ mov [edi+20], eax
+ mov eax, [ebx+24]
+ add eax, [esi+24]
+ mov [edi+24], eax
+ mov eax, [ebx+28]
+ add eax, [esi+28]
+ mov [edi+28], eax
+ mov eax, [ebx+32]
+ add eax, [esi+32]
+ mov [edi+32], eax
+ mov eax, [ebx+36]
+ add eax, [esi+36]
+ mov [edi+36], eax
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SUB}
+ mov eax, [ebx+0]
+ sub eax, [esi+0]
+ mov [edi+0], eax
+ mov eax, [ebx+4]
+ sub eax, [esi+4]
+ mov [edi+4], eax
+ mov eax, [ebx+8]
+ sub eax, [esi+8]
+ mov [edi+8], eax
+ mov eax, [ebx+12]
+ sub eax, [esi+12]
+ mov [edi+12], eax
+ mov eax, [ebx+16]
+ sub eax, [esi+16]
+ mov [edi+16], eax
+ mov eax, [ebx+20]
+ sub eax, [esi+20]
+ mov [edi+20], eax
+ mov eax, [ebx+24]
+ sub eax, [esi+24]
+ mov [edi+24], eax
+ mov eax, [ebx+28]
+ sub eax, [esi+28]
+ mov [edi+28], eax
+ mov eax, [ebx+32]
+ sub eax, [esi+32]
+ mov [edi+32], eax
+ mov eax, [ebx+36]
+ sub eax, [esi+36]
+ mov [edi+36], eax
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_APM}
+ push ebp
+ mov ebp, eax
+ mov eax, [ebx+0]
+ mov edx, [esi+0]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+0], ecx
+ sub eax, edx
+ mov [ebp+0], eax
+ mov eax, [ebx+4]
+ mov edx, [esi+4]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+4], ecx
+ sub eax, edx
+ mov [ebp+4], eax
+ mov eax, [ebx+8]
+ mov edx, [esi+8]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+8], ecx
+ sub eax, edx
+ mov [ebp+8], eax
+ mov eax, [ebx+12]
+ mov edx, [esi+12]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+12], ecx
+ sub eax, edx
+ mov [ebp+12], eax
+ mov eax, [ebx+16]
+ mov edx, [esi+16]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+16], ecx
+ sub eax, edx
+ mov [ebp+16], eax
+ mov eax, [ebx+20]
+ mov edx, [esi+20]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+20], ecx
+ sub eax, edx
+ mov [ebp+20], eax
+ mov eax, [ebx+24]
+ mov edx, [esi+24]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+24], ecx
+ sub eax, edx
+ mov [ebp+24], eax
+ mov eax, [ebx+28]
+ mov edx, [esi+28]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+28], ecx
+ sub eax, edx
+ mov [ebp+28], eax
+ mov eax, [ebx+32]
+ mov edx, [esi+32]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+32], ecx
+ sub eax, edx
+ mov [ebp+32], eax
+ mov eax, [ebx+36]
+ mov edx, [esi+36]
+ mov ecx, eax
+ add ecx, edx
+ mov [edi+36], ecx
+ sub eax, edx
+ mov [ebp+36], eax
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CSWAP}
+ neg ebx
+ mov eax, [esi+0]
+ mov edx, [edi+0]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+0], eax
+ mov [edi+0], edx
+ mov eax, [esi+4]
+ mov edx, [edi+4]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+4], eax
+ mov [edi+4], edx
+ mov eax, [esi+8]
+ mov edx, [edi+8]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+8], eax
+ mov [edi+8], edx
+ mov eax, [esi+12]
+ mov edx, [edi+12]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+12], eax
+ mov [edi+12], edx
+ mov eax, [esi+16]
+ mov edx, [edi+16]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+16], eax
+ mov [edi+16], edx
+ mov eax, [esi+20]
+ mov edx, [edi+20]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+20], eax
+ mov [edi+20], edx
+ mov eax, [esi+24]
+ mov edx, [edi+24]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+24], eax
+ mov [edi+24], edx
+ mov eax, [esi+28]
+ mov edx, [edi+28]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+28], eax
+ mov [edi+28], edx
+ mov eax, [esi+32]
+ mov edx, [edi+32]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+32], eax
+ mov [edi+32], edx
+ mov eax, [esi+36]
+ mov edx, [edi+36]
+ mov ecx, eax
+ xor ecx, edx
+ and ecx, ebx
+ xor eax, ecx
+ xor edx, ecx
+ mov [esi+36], eax
+ mov [edi+36], edx
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CARRY}
+ mov eax, [ebx+4]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+4], eax
+ add [ebx+8], ecx
+ mov eax, [ebx+12]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+12], eax
+ add [ebx+16], ecx
+ mov eax, [ebx+24]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+24], eax
+ add [ebx+28], ecx
+ mov eax, [ebx+32]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+32], eax
+ add [ebx+36], ecx
+ mov eax, [ebx+8]
+ mov ecx, eax
+ sar ecx, 25
+ and eax, $01FFFFFF
+ mov [ebx+8], eax
+ add [ebx+12], ecx
+ mov eax, [ebx+16]
+ mov ecx, eax
+ sar ecx, 25
+ and eax, $01FFFFFF
+ mov [ebx+16], eax
+ add [ebx+20], ecx
+ mov eax, [ebx+28]
+ mov ecx, eax
+ sar ecx, 25
+ and eax, $01FFFFFF
+ mov [ebx+28], eax
+ add [ebx+32], ecx
+ mov eax, [ebx+36]
+ mov ecx, eax
+ sar ecx, 25
+ imul ecx, ecx, 38
+ and eax, $01FFFFFF
+ mov [ebx+36], eax
+ add [ebx+0], ecx
+ mov eax, [ebx+0]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+0], eax
+ add [ebx+4], ecx
+ mov eax, [ebx+20]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+20], eax
+ add [ebx+24], ecx
+ mov eax, [ebx+4]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+4], eax
+ add [ebx+8], ecx
+ mov eax, [ebx+12]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+12], eax
+ add [ebx+16], ecx
+ mov eax, [ebx+24]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+24], eax
+ add [ebx+28], ecx
+ mov eax, [ebx+32]
+ mov ecx, eax
+ sar ecx, 26
+ and eax, $03FFFFFF
+ mov [ebx+32], eax
+ add [ebx+36], ecx
+ pop ebx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_MULWORD}
+ sub esp, 48
+ mov eax, [ebx+8]
+ imul esi
+ mov ecx, eax
+ and ecx, $01FFFFFF
+ mov [esp+32], ecx
+ shrd eax, edx, 25
+ sar edx, 25
+ mov [esp+0], eax
+ mov [esp+4], edx
+ mov eax, [ebx+16]
+ imul esi
+ mov ecx, eax
+ and ecx, $01FFFFFF
+ mov [esp+36], ecx
+ shrd eax, edx, 25
+ sar edx, 25
+ mov [esp+8], eax
+ mov [esp+12], edx
+ mov eax, [ebx+28]
+ imul esi
+ mov ecx, eax
+ and ecx, $01FFFFFF
+ mov [esp+40], ecx
+ shrd eax, edx, 25
+ sar edx, 25
+ mov [esp+16], eax
+ mov [esp+20], edx
+ mov eax, [ebx+36]
+ imul esi
+ mov ecx, eax
+ and ecx, $01FFFFFF
+ mov [esp+44], ecx
+ shrd eax, edx, 25
+ sar edx, 25
+ mov ecx, edx
+ mov edx, 38
+ mul edx
+ imul ecx, ecx, 38
+ add edx, ecx
+ mov [esp+24], eax
+ mov [esp+28], edx
+ mov eax, [ebx+0]
+ imul esi
+ add eax, [esp+24]
+ adc edx, [esp+28]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+0], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+24], eax
+ mov [esp+28], edx
+ mov eax, [ebx+20]
+ imul esi
+ add eax, [esp+8]
+ adc edx, [esp+12]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+20], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+8], eax
+ mov [esp+12], edx
+ mov eax, [ebx+4]
+ imul esi
+ add eax, [esp+24]
+ adc edx, [esp+28]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+4], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+24], eax
+ mov [esp+28], edx
+ mov eax, [ebx+12]
+ imul esi
+ add eax, [esp+0]
+ adc edx, [esp+4]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+12], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+0], eax
+ mov [esp+4], edx
+ mov eax, [ebx+24]
+ imul esi
+ add eax, [esp+8]
+ adc edx, [esp+12]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+24], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+8], eax
+ mov [esp+12], edx
+ mov eax, [ebx+32]
+ imul esi
+ add eax, [esp+16]
+ adc edx, [esp+20]
+ mov ecx, eax
+ and ecx, $03FFFFFF
+ mov [edi+32], ecx
+ shrd eax, edx, 26
+ sar edx, 26
+ mov [esp+16], eax
+ mov [esp+20], edx
+ mov eax, [esp+32]
+ add eax, [esp+24]
+ mov [edi+8], eax
+ mov eax, [esp+36]
+ add eax, [esp+0]
+ mov [edi+16], eax
+ mov eax, [esp+40]
+ add eax, [esp+8]
+ mov [edi+28], eax
+ mov eax, [esp+44]
+ add eax, [esp+16]
+ mov [edi+36], eax
+ add esp, 48
+ pop edi
+ pop esi
+ pop ebx
+{$ELSE}
+{$FATAL Define one of CRYPTOLIB_CURVE25519_MUL/SQR/ADD/SUB/APM/CSWAP/CARRY/MULWORD}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
diff --git a/CryptoLib/src/Include/Simd/Curve25519/X25519Field_x86_64.inc b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_x86_64.inc
new file mode 100644
index 00000000..6a51c2eb
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/Curve25519/X25519Field_x86_64.inc
@@ -0,0 +1,1294 @@
+// Curve25519 field kernels (x86-64), radix-2^25.5, ten signed Int32 limbs.
+// One selector-driven file; define exactly one of the following before the
+// include (each pairs with its ClpSimdProcBegin prologue):
+//
+// CRYPTOLIB_CURVE25519_MUL (Proc3: rcx=PF, rdx=PG, r8=PH)
+// PH := PF * PG
+// CRYPTOLIB_CURVE25519_SQR (Proc2: rcx=PX, rdx=PZ)
+// PZ := PX^2
+// CRYPTOLIB_CURVE25519_ADD (Proc3: rcx=PX, rdx=PY, r8=PZ)
+// PZ := PX + PY
+// CRYPTOLIB_CURVE25519_SUB (Proc3: rcx=PX, rdx=PY, r8=PZ)
+// PZ := PX - PY
+// CRYPTOLIB_CURVE25519_APM (Proc4: rcx=PX, rdx=PY, r8=PZp, r9=PZm)
+// PZp := PX+PY; PZm := PX-PY
+// CRYPTOLIB_CURVE25519_CSWAP (Proc3: rcx=ASwap, rdx=PA, r8=PB)
+// constant-time swap of PA, PB
+// CRYPTOLIB_CURVE25519_CARRY (Proc1: rcx=PZ)
+// carry-propagate (reduce) PZ in place
+// CRYPTOLIB_CURVE25519_MULWORD (Proc3: rcx=PX, rdx=AY, r8=PZ)
+// PZ := PX * AY (small scalar AY)
+//
+// Mul/Sqr are signed product-scanning schoolbook (stage Q[j]=19*g[j]; one
+// Int64 accumulator per column, <2^62.42; canonical carry with the 2^256==38
+// top fold). All results mod 2^255-19; signed limbs => imul only.
+// Constant-time: no data-dependent branches or addresses.
+{$IFDEF CRYPTOLIB_CURVE25519_MUL}
+ push rbx
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ push rbp
+ sub rsp, 240
+ movsxd rax, dword ptr [rcx+0]
+ mov [rsp+0], rax
+ movsxd rax, dword ptr [rcx+4]
+ mov [rsp+8], rax
+ movsxd rax, dword ptr [rcx+8]
+ mov [rsp+16], rax
+ movsxd rax, dword ptr [rcx+12]
+ mov [rsp+24], rax
+ movsxd rax, dword ptr [rcx+16]
+ mov [rsp+32], rax
+ movsxd rax, dword ptr [rcx+20]
+ mov [rsp+40], rax
+ movsxd rax, dword ptr [rcx+24]
+ mov [rsp+48], rax
+ movsxd rax, dword ptr [rcx+28]
+ mov [rsp+56], rax
+ movsxd rax, dword ptr [rcx+32]
+ mov [rsp+64], rax
+ movsxd rax, dword ptr [rcx+36]
+ mov [rsp+72], rax
+ movsxd rax, dword ptr [rdx+0]
+ mov [rsp+80], rax
+ movsxd rax, dword ptr [rdx+4]
+ mov [rsp+88], rax
+ movsxd rax, dword ptr [rdx+8]
+ mov [rsp+96], rax
+ movsxd rax, dword ptr [rdx+12]
+ mov [rsp+104], rax
+ movsxd rax, dword ptr [rdx+16]
+ mov [rsp+112], rax
+ movsxd rax, dword ptr [rdx+20]
+ mov [rsp+120], rax
+ movsxd rax, dword ptr [rdx+24]
+ mov [rsp+128], rax
+ movsxd rax, dword ptr [rdx+28]
+ mov [rsp+136], rax
+ movsxd rax, dword ptr [rdx+32]
+ mov [rsp+144], rax
+ movsxd rax, dword ptr [rdx+36]
+ mov [rsp+152], rax
+ imul rax, [rsp+88], 19
+ mov [rsp+168], rax
+ imul rax, [rsp+96], 19
+ mov [rsp+176], rax
+ imul rax, [rsp+104], 19
+ mov [rsp+184], rax
+ imul rax, [rsp+112], 19
+ mov [rsp+192], rax
+ imul rax, [rsp+120], 19
+ mov [rsp+200], rax
+ imul rax, [rsp+128], 19
+ mov [rsp+208], rax
+ imul rax, [rsp+136], 19
+ mov [rsp+216], rax
+ imul rax, [rsp+144], 19
+ mov [rsp+224], rax
+ imul rax, [rsp+152], 19
+ mov [rsp+232], rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+80]
+ mov rbx, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+224]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+208]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+200]
+ sal rax, 1
+ add rbx, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+192]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+184]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+176]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+168]
+ sal rax, 2
+ add rbx, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+88]
+ mov rsi, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+80]
+ add rsi, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add rsi, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+208]
+ sal rax, 1
+ add rsi, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+200]
+ sal rax, 1
+ add rsi, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+192]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+184]
+ sal rax, 1
+ add rsi, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+176]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+96]
+ mov rdi, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+88]
+ add rdi, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+80]
+ add rdi, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+232]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+216]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+208]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+200]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+192]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+184]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+104]
+ mov r9, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r9, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+88]
+ sal rax, 1
+ add r9, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+80]
+ add r9, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add r9, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+208]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+200]
+ sal rax, 1
+ add r9, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+192]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+112]
+ mov r10, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+104]
+ add r10, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+88]
+ add r10, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+80]
+ add r10, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+232]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add r10, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+208]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+200]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+120]
+ mov r11, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+112]
+ sal rax, 1
+ add r11, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+104]
+ sal rax, 1
+ add r11, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r11, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+88]
+ sal rax, 1
+ add r11, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+80]
+ add r11, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+224]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+208]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+128]
+ mov r12, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+120]
+ add r12, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+112]
+ sal rax, 1
+ add r12, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+104]
+ add r12, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r12, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+88]
+ add r12, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+80]
+ add r12, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add r12, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add r12, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+216]
+ sal rax, 2
+ add r12, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+136]
+ mov r13, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+128]
+ add r13, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+120]
+ add r13, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+112]
+ add r13, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+104]
+ add r13, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+96]
+ add r13, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+88]
+ add r13, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+80]
+ add r13, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+232]
+ sal rax, 1
+ add r13, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+224]
+ sal rax, 1
+ add r13, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+144]
+ mov r14, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+136]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+128]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+120]
+ add r14, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+112]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+104]
+ add r14, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+88]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+80]
+ add r14, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+232]
+ sal rax, 2
+ add r14, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+152]
+ mov r15, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+144]
+ add r15, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+136]
+ sal rax, 1
+ add r15, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+128]
+ add r15, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+120]
+ add r15, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+112]
+ add r15, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+104]
+ add r15, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+96]
+ sal rax, 1
+ add r15, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+88]
+ add r15, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+80]
+ add r15, rax
+ mov rax, rsi
+ sar rax, 26
+ add rdi, rax
+ and rsi, $03FFFFFF
+ mov rax, r9
+ sar rax, 26
+ add r10, rax
+ and r9, $03FFFFFF
+ mov rax, r12
+ sar rax, 26
+ add r13, rax
+ and r12, $03FFFFFF
+ mov rax, r14
+ sar rax, 26
+ add r15, rax
+ and r14, $03FFFFFF
+ mov rax, rdi
+ sar rax, 25
+ add r9, rax
+ and rdi, $01FFFFFF
+ mov rax, r10
+ sar rax, 25
+ add r11, rax
+ and r10, $01FFFFFF
+ mov rax, r13
+ sar rax, 25
+ add r14, rax
+ and r13, $01FFFFFF
+ mov rax, r15
+ sar rax, 25
+ imul rax, rax, 38
+ add rbx, rax
+ and r15, $01FFFFFF
+ mov rax, rbx
+ sar rax, 26
+ add rsi, rax
+ and rbx, $03FFFFFF
+ mov rax, r11
+ sar rax, 26
+ add r12, rax
+ and r11, $03FFFFFF
+ mov rax, rsi
+ sar rax, 26
+ add rdi, rax
+ and rsi, $03FFFFFF
+ mov rax, r9
+ sar rax, 26
+ add r10, rax
+ and r9, $03FFFFFF
+ mov rax, r12
+ sar rax, 26
+ add r13, rax
+ and r12, $03FFFFFF
+ mov rax, r14
+ sar rax, 26
+ add r15, rax
+ and r14, $03FFFFFF
+ mov [r8+0], ebx
+ mov [r8+4], esi
+ mov [r8+8], edi
+ mov [r8+12], r9d
+ mov [r8+16], r10d
+ mov [r8+20], r11d
+ mov [r8+24], r12d
+ mov [r8+28], r13d
+ mov [r8+32], r14d
+ mov [r8+36], r15d
+ add rsp, 240
+ pop rbp
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SQR}
+ push rbx
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ push rbp
+ sub rsp, 160
+ movsxd rax, dword ptr [rcx+0]
+ mov [rsp+0], rax
+ movsxd rax, dword ptr [rcx+4]
+ mov [rsp+8], rax
+ movsxd rax, dword ptr [rcx+8]
+ mov [rsp+16], rax
+ movsxd rax, dword ptr [rcx+12]
+ mov [rsp+24], rax
+ movsxd rax, dword ptr [rcx+16]
+ mov [rsp+32], rax
+ movsxd rax, dword ptr [rcx+20]
+ mov [rsp+40], rax
+ movsxd rax, dword ptr [rcx+24]
+ mov [rsp+48], rax
+ movsxd rax, dword ptr [rcx+28]
+ mov [rsp+56], rax
+ movsxd rax, dword ptr [rcx+32]
+ mov [rsp+64], rax
+ movsxd rax, dword ptr [rcx+36]
+ mov [rsp+72], rax
+ imul rax, [rsp+8], 19
+ mov [rsp+88], rax
+ imul rax, [rsp+16], 19
+ mov [rsp+96], rax
+ imul rax, [rsp+24], 19
+ mov [rsp+104], rax
+ imul rax, [rsp+32], 19
+ mov [rsp+112], rax
+ imul rax, [rsp+40], 19
+ mov [rsp+120], rax
+ imul rax, [rsp+48], 19
+ mov [rsp+128], rax
+ imul rax, [rsp+56], 19
+ mov [rsp+136], rax
+ imul rax, [rsp+64], 19
+ mov [rsp+144], rax
+ imul rax, [rsp+72], 19
+ mov [rsp+152], rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+0]
+ mov rbx, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+152]
+ sal rax, 3
+ add rbx, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+144]
+ sal rax, 3
+ add rbx, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+136]
+ sal rax, 3
+ add rbx, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+128]
+ sal rax, 3
+ add rbx, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+120]
+ sal rax, 1
+ add rbx, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+8]
+ sal rax, 1
+ mov rsi, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+152]
+ sal rax, 3
+ add rsi, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+144]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+136]
+ sal rax, 3
+ add rsi, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+128]
+ sal rax, 2
+ add rsi, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+16]
+ sal rax, 1
+ mov rdi, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+8]
+ add rdi, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+152]
+ sal rax, 2
+ add rdi, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+144]
+ sal rax, 2
+ add rdi, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+136]
+ sal rax, 2
+ add rdi, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+128]
+ sal rax, 1
+ add rdi, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+24]
+ sal rax, 1
+ mov r9, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+16]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+152]
+ sal rax, 3
+ add r9, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+144]
+ sal rax, 2
+ add r9, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+136]
+ sal rax, 3
+ add r9, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+32]
+ sal rax, 1
+ mov r10, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+24]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+16]
+ sal rax, 1
+ add r10, rax
+ mov rax, [rsp+40]
+ imul rax, [rsp+152]
+ sal rax, 2
+ add r10, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+144]
+ sal rax, 2
+ add r10, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+136]
+ sal rax, 2
+ add r10, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+40]
+ sal rax, 1
+ mov r11, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+32]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+24]
+ sal rax, 2
+ add r11, rax
+ mov rax, [rsp+48]
+ imul rax, [rsp+152]
+ sal rax, 3
+ add r11, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+144]
+ sal rax, 3
+ add r11, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+48]
+ sal rax, 1
+ mov r12, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+40]
+ sal rax, 1
+ add r12, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+32]
+ sal rax, 2
+ add r12, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+24]
+ add r12, rax
+ mov rax, [rsp+56]
+ imul rax, [rsp+152]
+ sal rax, 3
+ add r12, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+144]
+ sal rax, 1
+ add r12, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+56]
+ sal rax, 1
+ mov r13, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+48]
+ sal rax, 1
+ add r13, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+40]
+ sal rax, 1
+ add r13, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+32]
+ sal rax, 1
+ add r13, rax
+ mov rax, [rsp+64]
+ imul rax, [rsp+152]
+ sal rax, 2
+ add r13, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+64]
+ sal rax, 1
+ mov r14, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+56]
+ sal rax, 2
+ add r14, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+48]
+ sal rax, 2
+ add r14, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+40]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+32]
+ sal rax, 1
+ add r14, rax
+ mov rax, [rsp+72]
+ imul rax, [rsp+152]
+ sal rax, 2
+ add r14, rax
+ mov rax, [rsp+0]
+ imul rax, [rsp+72]
+ sal rax, 1
+ mov r15, rax
+ mov rax, [rsp+8]
+ imul rax, [rsp+64]
+ sal rax, 1
+ add r15, rax
+ mov rax, [rsp+16]
+ imul rax, [rsp+56]
+ sal rax, 2
+ add r15, rax
+ mov rax, [rsp+24]
+ imul rax, [rsp+48]
+ sal rax, 1
+ add r15, rax
+ mov rax, [rsp+32]
+ imul rax, [rsp+40]
+ sal rax, 1
+ add r15, rax
+ mov rax, rsi
+ sar rax, 26
+ add rdi, rax
+ and rsi, $03FFFFFF
+ mov rax, r9
+ sar rax, 26
+ add r10, rax
+ and r9, $03FFFFFF
+ mov rax, r12
+ sar rax, 26
+ add r13, rax
+ and r12, $03FFFFFF
+ mov rax, r14
+ sar rax, 26
+ add r15, rax
+ and r14, $03FFFFFF
+ mov rax, rdi
+ sar rax, 25
+ add r9, rax
+ and rdi, $01FFFFFF
+ mov rax, r10
+ sar rax, 25
+ add r11, rax
+ and r10, $01FFFFFF
+ mov rax, r13
+ sar rax, 25
+ add r14, rax
+ and r13, $01FFFFFF
+ mov rax, r15
+ sar rax, 25
+ imul rax, rax, 38
+ add rbx, rax
+ and r15, $01FFFFFF
+ mov rax, rbx
+ sar rax, 26
+ add rsi, rax
+ and rbx, $03FFFFFF
+ mov rax, r11
+ sar rax, 26
+ add r12, rax
+ and r11, $03FFFFFF
+ mov rax, rsi
+ sar rax, 26
+ add rdi, rax
+ and rsi, $03FFFFFF
+ mov rax, r9
+ sar rax, 26
+ add r10, rax
+ and r9, $03FFFFFF
+ mov rax, r12
+ sar rax, 26
+ add r13, rax
+ and r12, $03FFFFFF
+ mov rax, r14
+ sar rax, 26
+ add r15, rax
+ and r14, $03FFFFFF
+ mov [rdx+0], ebx
+ mov [rdx+4], esi
+ mov [rdx+8], edi
+ mov [rdx+12], r9d
+ mov [rdx+16], r10d
+ mov [rdx+20], r11d
+ mov [rdx+24], r12d
+ mov [rdx+28], r13d
+ mov [rdx+32], r14d
+ mov [rdx+36], r15d
+ add rsp, 160
+ pop rbp
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_ADD}
+ mov eax, [rcx+0]
+ add eax, [rdx+0]
+ mov [r8+0], eax
+ mov eax, [rcx+4]
+ add eax, [rdx+4]
+ mov [r8+4], eax
+ mov eax, [rcx+8]
+ add eax, [rdx+8]
+ mov [r8+8], eax
+ mov eax, [rcx+12]
+ add eax, [rdx+12]
+ mov [r8+12], eax
+ mov eax, [rcx+16]
+ add eax, [rdx+16]
+ mov [r8+16], eax
+ mov eax, [rcx+20]
+ add eax, [rdx+20]
+ mov [r8+20], eax
+ mov eax, [rcx+24]
+ add eax, [rdx+24]
+ mov [r8+24], eax
+ mov eax, [rcx+28]
+ add eax, [rdx+28]
+ mov [r8+28], eax
+ mov eax, [rcx+32]
+ add eax, [rdx+32]
+ mov [r8+32], eax
+ mov eax, [rcx+36]
+ add eax, [rdx+36]
+ mov [r8+36], eax
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_SUB}
+ mov eax, [rcx+0]
+ sub eax, [rdx+0]
+ mov [r8+0], eax
+ mov eax, [rcx+4]
+ sub eax, [rdx+4]
+ mov [r8+4], eax
+ mov eax, [rcx+8]
+ sub eax, [rdx+8]
+ mov [r8+8], eax
+ mov eax, [rcx+12]
+ sub eax, [rdx+12]
+ mov [r8+12], eax
+ mov eax, [rcx+16]
+ sub eax, [rdx+16]
+ mov [r8+16], eax
+ mov eax, [rcx+20]
+ sub eax, [rdx+20]
+ mov [r8+20], eax
+ mov eax, [rcx+24]
+ sub eax, [rdx+24]
+ mov [r8+24], eax
+ mov eax, [rcx+28]
+ sub eax, [rdx+28]
+ mov [r8+28], eax
+ mov eax, [rcx+32]
+ sub eax, [rdx+32]
+ mov [r8+32], eax
+ mov eax, [rcx+36]
+ sub eax, [rdx+36]
+ mov [r8+36], eax
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_APM}
+ mov eax, [rcx+0]
+ mov r11d, [rdx+0]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+0], eax
+ sub r10d, r11d
+ mov [r9+0], r10d
+ mov eax, [rcx+4]
+ mov r11d, [rdx+4]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+4], eax
+ sub r10d, r11d
+ mov [r9+4], r10d
+ mov eax, [rcx+8]
+ mov r11d, [rdx+8]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+8], eax
+ sub r10d, r11d
+ mov [r9+8], r10d
+ mov eax, [rcx+12]
+ mov r11d, [rdx+12]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+12], eax
+ sub r10d, r11d
+ mov [r9+12], r10d
+ mov eax, [rcx+16]
+ mov r11d, [rdx+16]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+16], eax
+ sub r10d, r11d
+ mov [r9+16], r10d
+ mov eax, [rcx+20]
+ mov r11d, [rdx+20]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+20], eax
+ sub r10d, r11d
+ mov [r9+20], r10d
+ mov eax, [rcx+24]
+ mov r11d, [rdx+24]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+24], eax
+ sub r10d, r11d
+ mov [r9+24], r10d
+ mov eax, [rcx+28]
+ mov r11d, [rdx+28]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+28], eax
+ sub r10d, r11d
+ mov [r9+28], r10d
+ mov eax, [rcx+32]
+ mov r11d, [rdx+32]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+32], eax
+ sub r10d, r11d
+ mov [r9+32], r10d
+ mov eax, [rcx+36]
+ mov r11d, [rdx+36]
+ mov r10d, eax
+ add eax, r11d
+ mov [r8+36], eax
+ sub r10d, r11d
+ mov [r9+36], r10d
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CSWAP}
+ neg ecx
+ mov eax, [rdx+0]
+ mov r10d, [r8+0]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+0], eax
+ mov [r8+0], r10d
+ mov eax, [rdx+4]
+ mov r10d, [r8+4]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+4], eax
+ mov [r8+4], r10d
+ mov eax, [rdx+8]
+ mov r10d, [r8+8]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+8], eax
+ mov [r8+8], r10d
+ mov eax, [rdx+12]
+ mov r10d, [r8+12]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+12], eax
+ mov [r8+12], r10d
+ mov eax, [rdx+16]
+ mov r10d, [r8+16]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+16], eax
+ mov [r8+16], r10d
+ mov eax, [rdx+20]
+ mov r10d, [r8+20]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+20], eax
+ mov [r8+20], r10d
+ mov eax, [rdx+24]
+ mov r10d, [r8+24]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+24], eax
+ mov [r8+24], r10d
+ mov eax, [rdx+28]
+ mov r10d, [r8+28]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+28], eax
+ mov [r8+28], r10d
+ mov eax, [rdx+32]
+ mov r10d, [r8+32]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+32], eax
+ mov [r8+32], r10d
+ mov eax, [rdx+36]
+ mov r10d, [r8+36]
+ mov r9d, eax
+ xor r9d, r10d
+ and r9d, ecx
+ xor eax, r9d
+ xor r10d, r9d
+ mov [rdx+36], eax
+ mov [r8+36], r10d
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_CARRY}
+ push rbx
+ push rsi
+ push rdi
+ push r12
+ push rbp
+ mov eax, [rcx+0]
+ mov edx, [rcx+4]
+ mov r8d, [rcx+8]
+ mov r9d, [rcx+12]
+ mov r10d, [rcx+16]
+ mov r11d, [rcx+20]
+ mov ebx, [rcx+24]
+ mov esi, [rcx+28]
+ mov edi, [rcx+32]
+ mov r12d, [rcx+36]
+ mov ebp, edx
+ sar ebp, 26
+ add r8d, ebp
+ and edx, $03FFFFFF
+ mov ebp, r9d
+ sar ebp, 26
+ add r10d, ebp
+ and r9d, $03FFFFFF
+ mov ebp, ebx
+ sar ebp, 26
+ add esi, ebp
+ and ebx, $03FFFFFF
+ mov ebp, edi
+ sar ebp, 26
+ add r12d, ebp
+ and edi, $03FFFFFF
+ mov ebp, r8d
+ sar ebp, 25
+ add r9d, ebp
+ and r8d, $01FFFFFF
+ mov ebp, r10d
+ sar ebp, 25
+ add r11d, ebp
+ and r10d, $01FFFFFF
+ mov ebp, esi
+ sar ebp, 25
+ add edi, ebp
+ and esi, $01FFFFFF
+ mov ebp, r12d
+ sar ebp, 25
+ imul ebp, ebp, 38
+ add eax, ebp
+ and r12d, $01FFFFFF
+ mov ebp, eax
+ sar ebp, 26
+ add edx, ebp
+ and eax, $03FFFFFF
+ mov ebp, r11d
+ sar ebp, 26
+ add ebx, ebp
+ and r11d, $03FFFFFF
+ mov ebp, edx
+ sar ebp, 26
+ add r8d, ebp
+ and edx, $03FFFFFF
+ mov ebp, r9d
+ sar ebp, 26
+ add r10d, ebp
+ and r9d, $03FFFFFF
+ mov ebp, ebx
+ sar ebp, 26
+ add esi, ebp
+ and ebx, $03FFFFFF
+ mov ebp, edi
+ sar ebp, 26
+ add r12d, ebp
+ and edi, $03FFFFFF
+ mov [rcx+0], eax
+ mov [rcx+4], edx
+ mov [rcx+8], r8d
+ mov [rcx+12], r9d
+ mov [rcx+16], r10d
+ mov [rcx+20], r11d
+ mov [rcx+24], ebx
+ mov [rcx+28], esi
+ mov [rcx+32], edi
+ mov [rcx+36], r12d
+ pop rbp
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbx
+{$ELSE}
+{$IFDEF CRYPTOLIB_CURVE25519_MULWORD}
+ push rbx
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ movsxd r11, edx
+ movsxd rax, dword ptr [rcx+8]
+ imul rax, r11
+ mov edi, eax
+ and edi, $01FFFFFF
+ sar rax, 25
+ mov r9, rax
+ movsxd rax, dword ptr [rcx+16]
+ imul rax, r11
+ mov r12d, eax
+ and r12d, $01FFFFFF
+ sar rax, 25
+ mov r10, rax
+ movsxd rax, dword ptr [rcx+28]
+ imul rax, r11
+ mov r13d, eax
+ and r13d, $01FFFFFF
+ sar rax, 25
+ mov rbx, rax
+ movsxd rax, dword ptr [rcx+36]
+ imul rax, r11
+ mov r14d, eax
+ and r14d, $01FFFFFF
+ sar rax, 25
+ mov rsi, rax
+ imul rsi, rsi, 38
+ movsxd rax, dword ptr [rcx+0]
+ imul rax, r11
+ add rsi, rax
+ mov eax, esi
+ and eax, $03FFFFFF
+ mov [r8+0], eax
+ sar rsi, 26
+ movsxd rax, dword ptr [rcx+20]
+ imul rax, r11
+ add r10, rax
+ mov eax, r10d
+ and eax, $03FFFFFF
+ mov [r8+20], eax
+ sar r10, 26
+ movsxd rax, dword ptr [rcx+4]
+ imul rax, r11
+ add rsi, rax
+ mov eax, esi
+ and eax, $03FFFFFF
+ mov [r8+4], eax
+ sar rsi, 26
+ movsxd rax, dword ptr [rcx+12]
+ imul rax, r11
+ add r9, rax
+ mov eax, r9d
+ and eax, $03FFFFFF
+ mov [r8+12], eax
+ sar r9, 26
+ movsxd rax, dword ptr [rcx+24]
+ imul rax, r11
+ add r10, rax
+ mov eax, r10d
+ and eax, $03FFFFFF
+ mov [r8+24], eax
+ sar r10, 26
+ movsxd rax, dword ptr [rcx+32]
+ imul rax, r11
+ add rbx, rax
+ mov eax, ebx
+ and eax, $03FFFFFF
+ mov [r8+32], eax
+ sar rbx, 26
+ mov eax, edi
+ add eax, esi
+ mov [r8+8], eax
+ mov eax, r12d
+ add eax, r9d
+ mov [r8+16], eax
+ mov eax, r13d
+ add eax, r10d
+ mov [r8+28], eax
+ mov eax, r14d
+ add eax, ebx
+ mov [r8+36], eax
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbx
+{$ELSE}
+{$FATAL Define one of CRYPTOLIB_CURVE25519_MUL/SQR/ADD/SUB/APM/CSWAP/CARRY/MULWORD}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
+{$ENDIF}
diff --git a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
index 65813449..4abbcf40 100644
--- a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
+++ b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
@@ -25,6 +25,7 @@ interface
ClpNat,
ClpBitOperations,
ClpArrayUtilities,
+ ClpCurveFieldSimd,
ClpCryptoLibTypes;
type
@@ -126,6 +127,8 @@ class procedure TX25519Field.Add(const AX, AY, AZ: TCryptoLibInt32Array);
var
LI: Int32;
begin
+ if TCurveFieldSimd.TryAdd25519(AX, AY, AZ) then
+ Exit;
LI := 0;
while LI < Size do
begin
@@ -149,6 +152,8 @@ class procedure TX25519Field.Apm(const AX, AY, AZp, AZm: TCryptoLibInt32Array);
LI: Int32;
LXi, LYi: Int32;
begin
+ if TCurveFieldSimd.TryApm25519(AX, AY, AZp, AZm) then
+ Exit;
LI := 0;
while LI < Size do
begin
@@ -184,6 +189,8 @@ class procedure TX25519Field.Carry(AZ: TCryptoLibInt32Array);
var
Lz0, Lz1, Lz2, Lz3, Lz4, Lz5, Lz6, Lz7, Lz8, Lz9: Int32;
begin
+ if TCurveFieldSimd.TryCarry25519(AZ) then
+ Exit;
Lz0 := AZ[0];
Lz1 := AZ[1];
Lz2 := AZ[2];
@@ -290,6 +297,8 @@ class procedure TX25519Field.CSwap(ASwap: Int32; AA, AB: TCryptoLibInt32Array);
LI: Int32;
Lai, Lbi, Ldummy: Int32;
begin
+ if TCurveFieldSimd.TryCSwap25519(ASwap, AA, AB) then
+ Exit;
Lmask := 0 - ASwap;
LI := 0;
while LI < Size do
@@ -556,6 +565,8 @@ class procedure TX25519Field.Mul(const AX: TCryptoLibInt32Array; AY: Int32; cons
Lx0, Lx1, Lx2, Lx3, Lx4, Lx5, Lx6, Lx7, Lx8, Lx9: Int32;
Lc0, Lc1, Lc2, Lc3: Int64;
begin
+ if TCurveFieldSimd.TryMulWord25519(AX, AY, AZ) then
+ Exit;
Lx0 := AX[0];
Lx1 := AX[1];
Lx2 := AX[2];
@@ -613,6 +624,8 @@ class procedure TX25519Field.Mul(const AX, AY, AZ: TCryptoLibInt32Array);
Lt: Int64;
Lz8, Lz9: Int32;
begin
+ if TCurveFieldSimd.TryMul25519(AX, AY, AZ) then
+ Exit;
Lx0 := AX[0];
Ly0 := AY[0];
Lx1 := AX[1];
@@ -839,6 +852,8 @@ class procedure TX25519Field.Sqr(const AX, AZ: TCryptoLibInt32Array);
Lt: Int64;
Lz8, Lz9: Int32;
begin
+ if TCurveFieldSimd.TrySqr25519(AX, AZ) then
+ Exit;
Lx0 := AX[0];
Lx1 := AX[1];
Lx2 := AX[2];
@@ -989,6 +1004,8 @@ class procedure TX25519Field.Sub(const AX, AY, AZ: TCryptoLibInt32Array);
var
LI: Int32;
begin
+ if TCurveFieldSimd.TrySub25519(AX, AY, AZ) then
+ Exit;
LI := 0;
while LI < Size do
begin
diff --git a/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk b/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
index d4e427d8..f184b0bb 100644
--- a/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
+++ b/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
@@ -219,8 +219,11 @@ contains
ClpChaChaX86Backend in '..\..\Simd\Backend\ClpChaChaX86Backend.pas',
ClpChaChaArmBackend in '..\..\Simd\Backend\ClpChaChaArmBackend.pas',
ClpFpKernelSimd in '..\..\Simd\Facade\ClpFpKernelSimd.pas',
+ ClpCurveFieldSimd in '..\..\Simd\Facade\ClpCurveFieldSimd.pas',
ClpFpKernelX86Backend in '..\..\Simd\Backend\ClpFpKernelX86Backend.pas',
+ ClpCurveFieldX86Backend in '..\..\Simd\Backend\ClpCurveFieldX86Backend.pas',
ClpFpKernelArmBackend in '..\..\Simd\Backend\ClpFpKernelArmBackend.pas',
+ ClpCurveFieldArmBackend in '..\..\Simd\Backend\ClpCurveFieldArmBackend.pas',
ClpSalsaSimd in '..\..\Simd\Facade\ClpSalsaSimd.pas',
ClpSalsaX86Backend in '..\..\Simd\Backend\ClpSalsaX86Backend.pas',
ClpSalsaArmBackend in '..\..\Simd\Backend\ClpSalsaArmBackend.pas',
diff --git a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
index fa39017c..4f2d5ec8 100644
--- a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
+++ b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
@@ -15,7 +15,7 @@
-
+
@@ -31,7 +31,7 @@
Acknowledgements:
Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
-
+
@@ -3525,6 +3525,18 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
index ab0d3c54..09bffa76 100644
--- a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
+++ b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
@@ -284,7 +284,8 @@ interface
ClpAbstractBlockCipherMode, ClpAbstractAeadCipher,
ClpAbstractAeadBlockCipher, ClpFpKernelX86Backend, ClpFpKernelSimd,
ClpFpKernelArmBackend, ClpCTFieldValue, ClpCTFieldArith, ClpCTPoint,
- ClpFpCTMultiplier, ClpFpCombMultiplier;
+ ClpFpCTMultiplier, ClpFpCombMultiplier, ClpCurveFieldSimd,
+ ClpCurveFieldX86Backend, ClpCurveFieldArmBackend;
implementation
diff --git a/CryptoLib/src/Simd/Backend/ClpCurveFieldArmBackend.pas b/CryptoLib/src/Simd/Backend/ClpCurveFieldArmBackend.pas
new file mode 100644
index 00000000..4ecb4aa6
--- /dev/null
+++ b/CryptoLib/src/Simd/Backend/ClpCurveFieldArmBackend.pas
@@ -0,0 +1,186 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * Distributed under the MIT software license, see the accompanying file LICENSE * }
+{ * or visit http://www.opensource.org/licenses/mit-license.php. * }
+{ * * }
+{ * Acknowledgements: * }
+{ * * }
+{ * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpCurveFieldArmBackend;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ ClpCpuFeatures,
+ ClpSimdLevels,
+{$ENDIF}
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// AArch64 kernel backend for the reduced-radix curve fields (RFC 7748/8032).
+ /// A leaf: capability probe plus the hot signed operand-scanning multiply/
+ /// square. The arch-neutral dispatch and the scalar fallback live in
+ /// TCurveFieldSimd / the field units. Hot paths are in
+ /// Include/Simd/Curve25519/.
+ ///
+ TCurveFieldArmBackend = class sealed
+ public
+ class function IsSupported: Boolean; static;
+ class procedure Mul25519(PF, PG, PH: Pointer); static;
+ class procedure Sqr25519(PX, PZ: Pointer); static;
+ class procedure Add25519(PX, PY, PZ: Pointer); static;
+ class procedure Sub25519(PX, PY, PZ: Pointer); static;
+ class procedure Apm25519(PX, PY, PZp, PZm: Pointer); static;
+ class procedure CSwap25519(ASwap: NativeInt; PA, PB: Pointer); static;
+ class procedure Carry25519(PZ: Pointer); static;
+ class procedure MulWord25519(PX: Pointer; AY: NativeInt; PZ: Pointer); static;
+ end;
+
+implementation
+
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+
+// PH[0..9] := PF[0..9] * PG[0..9] (mod 2^255-19), ten signed Int32 limbs.
+procedure FeMul25519Asm(PF, PG, PH: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_MUL}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_MUL}
+end;
+
+// PZ[0..9] := PX[0..9]^2 (mod 2^255-19), ten signed Int32 limbs.
+procedure FeSqr25519Asm(PX, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_SQR}
+{$I ..\..\Include\Simd\Common\ClpSimdProc2Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_SQR}
+end;
+
+// 25519 small-op kernels (branch-free).
+procedure FeAdd25519Asm(PX, PY, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_ADD}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_ADD}
+end;
+
+procedure FeSub25519Asm(PX, PY, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_SUB}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_SUB}
+end;
+
+procedure FeApm25519Asm(PX, PY, PZp, PZm: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_APM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc4Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_APM}
+end;
+
+procedure FeCSwap25519Asm(ASwap: NativeInt; PA, PB: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_CSWAP}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_CSWAP}
+end;
+
+procedure FeCarry25519Asm(PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_CARRY}
+{$I ..\..\Include\Simd\Common\ClpSimdProc1Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_CARRY}
+end;
+
+procedure FeMulWord25519Asm(PX: Pointer; AY: NativeInt; PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_MULWORD}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_aarch64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_aarch64.inc}
+{$UNDEF CRYPTOLIB_CURVE25519_MULWORD}
+end;
+
+{$ENDIF}
+
+{ TCurveFieldArmBackend }
+
+class function TCurveFieldArmBackend.IsSupported: Boolean;
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ // Kernels use plain integer ops (no CPU-feature dependency); gate only on
+ // "not forced scalar" so a CRYPTOLIB_FORCE_SCALAR build (which pins the active
+ // level to Scalar) falls back to the scalar path.
+ Result := TCpuFeatures.Arm.GetActiveSimdLevel() <> TArmSimdLevel.Scalar;
+{$ELSE}
+ Result := False;
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Mul25519(PF, PG, PH: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeMul25519Asm(PF, PG, PH);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Add25519(PX, PY, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeAdd25519Asm(PX, PY, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Sub25519(PX, PY, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeSub25519Asm(PX, PY, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Apm25519(PX, PY, PZp, PZm: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeApm25519Asm(PX, PY, PZp, PZm);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.CSwap25519(ASwap: NativeInt; PA, PB: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeCSwap25519Asm(ASwap, PA, PB);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Carry25519(PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeCarry25519Asm(PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.MulWord25519(PX: Pointer; AY: NativeInt; PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeMulWord25519Asm(PX, AY, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldArmBackend.Sqr25519(PX, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ FeSqr25519Asm(PX, PZ);
+{$ENDIF}
+end;
+
+end.
diff --git a/CryptoLib/src/Simd/Backend/ClpCurveFieldX86Backend.pas b/CryptoLib/src/Simd/Backend/ClpCurveFieldX86Backend.pas
new file mode 100644
index 00000000..f9bbba67
--- /dev/null
+++ b/CryptoLib/src/Simd/Backend/ClpCurveFieldX86Backend.pas
@@ -0,0 +1,234 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * Distributed under the MIT software license, see the accompanying file LICENSE * }
+{ * or visit http://www.opensource.org/licenses/mit-license.php. * }
+{ * * }
+{ * Acknowledgements: * }
+{ * * }
+{ * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpCurveFieldX86Backend;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ ClpCpuFeatures,
+ ClpSimdLevels,
+{$ENDIF}
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// x86 (i386 + x86-64) kernel backend for the reduced-radix curve fields
+ /// (RFC 7748/8032). A leaf: capability probe plus the hot signed-schoolbook
+ /// multiply/square. The arch-neutral dispatch and the scalar fallback live in
+ /// TCurveFieldSimd / the field units. Hot paths are in
+ /// Include/Simd/Curve25519/.
+ ///
+ TCurveFieldX86Backend = class sealed
+ public
+ class function IsSupported: Boolean; static;
+ class procedure Mul25519(PF, PG, PH: Pointer); static;
+ class procedure Sqr25519(PX, PZ: Pointer); static;
+ class procedure Add25519(PX, PY, PZ: Pointer); static;
+ class procedure Sub25519(PX, PY, PZ: Pointer); static;
+ class procedure Apm25519(PX, PY, PZp, PZm: Pointer); static;
+ class procedure CSwap25519(ASwap: NativeInt; PA, PB: Pointer); static;
+ class procedure Carry25519(PZ: Pointer); static;
+ class procedure MulWord25519(PX: Pointer; AY: NativeInt; PZ: Pointer); static;
+ end;
+
+implementation
+
+{$IFDEF CRYPTOLIB_X86_SIMD}
+
+// PH[0..9] := PF[0..9] * PG[0..9] (mod 2^255-19), ten signed Int32 limbs.
+procedure FeMul25519Asm(PF, PG, PH: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_MUL}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_MUL}
+end;
+
+// PZ[0..9] := PX[0..9]^2 (mod 2^255-19), ten signed Int32 limbs.
+procedure FeSqr25519Asm(PX, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_SQR}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc2Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc2Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_SQR}
+end;
+
+// 25519 small-op kernels (branch-free).
+procedure FeAdd25519Asm(PX, PY, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_ADD}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_ADD}
+end;
+
+procedure FeSub25519Asm(PX, PY, PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_SUB}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_SUB}
+end;
+
+procedure FeApm25519Asm(PX, PY, PZp, PZm: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_APM}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc4Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc4Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_APM}
+end;
+
+procedure FeCSwap25519Asm(ASwap: NativeInt; PA, PB: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_CSWAP}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_CSWAP}
+end;
+
+procedure FeCarry25519Asm(PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_CARRY}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc1Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc1Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_CARRY}
+end;
+
+procedure FeMulWord25519Asm(PX: Pointer; AY: NativeInt; PZ: Pointer);
+{$DEFINE CRYPTOLIB_CURVE25519_MULWORD}
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_x86_64.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\ClpSimdProc3Begin_i386.inc}
+{$I ..\..\Include\Simd\Curve25519\X25519Field_i386.inc}
+{$ENDIF}
+{$UNDEF CRYPTOLIB_CURVE25519_MULWORD}
+end;
+
+{$ENDIF}
+
+{ TCurveFieldX86Backend }
+
+class function TCurveFieldX86Backend.IsSupported: Boolean;
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ // Kernels use plain integer ops (no CPU-feature dependency); gate only on
+ // "not forced scalar" so a CRYPTOLIB_FORCE_SCALAR build (which pins the active
+ // level to Scalar) falls back to the scalar path.
+ Result := TCpuFeatures.X86.GetActiveSimdLevel() <> TX86SimdLevel.Scalar;
+{$ELSE}
+ Result := False;
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Mul25519(PF, PG, PH: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeMul25519Asm(PF, PG, PH);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Sqr25519(PX, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeSqr25519Asm(PX, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Add25519(PX, PY, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeAdd25519Asm(PX, PY, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Sub25519(PX, PY, PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeSub25519Asm(PX, PY, PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Apm25519(PX, PY, PZp, PZm: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeApm25519Asm(PX, PY, PZp, PZm);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.CSwap25519(ASwap: NativeInt; PA, PB: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeCSwap25519Asm(ASwap, PA, PB);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.Carry25519(PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeCarry25519Asm(PZ);
+{$ENDIF}
+end;
+
+class procedure TCurveFieldX86Backend.MulWord25519(PX: Pointer; AY: NativeInt; PZ: Pointer);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ FeMulWord25519Asm(PX, AY, PZ);
+{$ENDIF}
+end;
+
+end.
diff --git a/CryptoLib/src/Simd/Facade/ClpCurveFieldSimd.pas b/CryptoLib/src/Simd/Facade/ClpCurveFieldSimd.pas
new file mode 100644
index 00000000..14752a94
--- /dev/null
+++ b/CryptoLib/src/Simd/Facade/ClpCurveFieldSimd.pas
@@ -0,0 +1,199 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * Distributed under the MIT software license, see the accompanying file LICENSE * }
+{ * or visit http://www.opensource.org/licenses/mit-license.php. * }
+{ * * }
+{ * Acknowledgements: * }
+{ * * }
+{ * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpCurveFieldSimd;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ ClpCurveFieldX86Backend,
+{$ENDIF}
+{$IFDEF CRYPTOLIB_AARCH64_ASM}
+ ClpCurveFieldArmBackend,
+{$ENDIF}
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// Arch-neutral facade over the reduced-radix curve field (RFC 7748/8032)
+ /// multiply/square kernels. The X25519/Ed25519 field is radix-2^25.5 (ten
+ /// signed Int32 limbs); the X448/Ed448 field is radix-2^28 (sixteen signed
+ /// Int32 limbs). Each Try* runs the fully-reduced field operation and
+ /// returns False when no fast path applies (unsupported arch or a
+ /// forced-scalar build); the caller then uses its existing Pascal path.
+ ///
+ TCurveFieldSimd = class sealed
+ public
+ /// AH := AF * AG (mod 2^255-19), ten signed Int32 limbs each.
+ class function TryMul25519(const AF, AG, AH: TCryptoLibInt32Array): Boolean; static;
+ /// AZ := AX^2 (mod 2^255-19), ten signed Int32 limbs.
+ class function TrySqr25519(const AX, AZ: TCryptoLibInt32Array): Boolean; static;
+ /// AZ := AX + AY (unreduced), ten Int32 limbs.
+ class function TryAdd25519(const AX, AY, AZ: TCryptoLibInt32Array): Boolean; static;
+ /// AZ := AX - AY (unreduced), ten Int32 limbs.
+ class function TrySub25519(const AX, AY, AZ: TCryptoLibInt32Array): Boolean; static;
+ /// AZp := AX+AY; AZm := AX-AY (unreduced), ten Int32 limbs.
+ class function TryApm25519(const AX, AY, AZp, AZm: TCryptoLibInt32Array): Boolean; static;
+ /// Constant-time conditional swap of AA and AB when ASwap=1.
+ class function TryCSwap25519(ASwap: Int32; const AA, AB: TCryptoLibInt32Array): Boolean; static;
+ /// AZ := carry-propagated AZ (radix-2^25.5 reduce).
+ class function TryCarry25519(const AZ: TCryptoLibInt32Array): Boolean; static;
+ /// AZ := AX * AY (mod 2^255-19), AY a small signed scalar.
+ class function TryMulWord25519(const AX: TCryptoLibInt32Array; AY: Int32;
+ const AZ: TCryptoLibInt32Array): Boolean; static;
+ end;
+
+implementation
+
+{ TCurveFieldSimd }
+
+class function TCurveFieldSimd.TryMul25519(const AF, AG, AH: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then
+ Exit(False);
+ TCurveFieldX86Backend.Mul25519(@AF[0], @AG[0], @AH[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then
+ Exit(False);
+ TCurveFieldArmBackend.Mul25519(@AF[0], @AG[0], @AH[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TrySqr25519(const AX, AZ: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then
+ Exit(False);
+ TCurveFieldX86Backend.Sqr25519(@AX[0], @AZ[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then
+ Exit(False);
+ TCurveFieldArmBackend.Sqr25519(@AX[0], @AZ[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TryAdd25519(const AX, AY, AZ: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.Add25519(@AX[0], @AY[0], @AZ[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.Add25519(@AX[0], @AY[0], @AZ[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TrySub25519(const AX, AY, AZ: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.Sub25519(@AX[0], @AY[0], @AZ[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.Sub25519(@AX[0], @AY[0], @AZ[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TryApm25519(const AX, AY, AZp, AZm: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.Apm25519(@AX[0], @AY[0], @AZp[0], @AZm[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.Apm25519(@AX[0], @AY[0], @AZp[0], @AZm[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TryCSwap25519(ASwap: Int32; const AA, AB: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.CSwap25519(ASwap, @AA[0], @AB[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.CSwap25519(ASwap, @AA[0], @AB[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TryCarry25519(const AZ: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.Carry25519(@AZ[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.Carry25519(@AZ[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+class function TCurveFieldSimd.TryMulWord25519(const AX: TCryptoLibInt32Array;
+ AY: Int32; const AZ: TCryptoLibInt32Array): Boolean;
+begin
+{$IF DEFINED(CRYPTOLIB_X86_SIMD) OR DEFINED(CRYPTOLIB_AARCH64_ASM)}
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if not TCurveFieldX86Backend.IsSupported then Exit(False);
+ TCurveFieldX86Backend.MulWord25519(@AX[0], AY, @AZ[0]);
+ {$ELSE}
+ if not TCurveFieldArmBackend.IsSupported then Exit(False);
+ TCurveFieldArmBackend.MulWord25519(@AX[0], AY, @AZ[0]);
+ {$ENDIF}
+ Result := True;
+{$ELSE}
+ Result := False;
+{$IFEND}
+end;
+
+end.