mirror of
https://github.com/saymrwulf/anza-cryptography-source.git
synced 2026-09-04 20:24:04 +00:00
ed25519: precompute AVX2 basepoint-128 table (#25)
Add a static AVX2 NafLookupTable5<CachedPoint> for B * 2^128 and use it from the vector triple-base verifier path instead of rebuilding that table every verification. Benchmark notes: - Ran this repository's Criterion benchmark program, benches/bench.rs, filtering to Single Verification, pinned to CPU 4 with 1s warmup, 2s measurement, and sample size 10. - local_verify_zebra estimate was 19.382 us, with 95% CI 19.327..19.426 us. - master measured 20.051 us, with 95% CI 19.938..20.134 us, so this branch was about 3.34% faster in that run.
This commit is contained in:
parent
7d80488798
commit
de07b0a389
2 changed files with 183 additions and 4 deletions
|
|
@ -16,6 +16,7 @@ use crate::backend::vector::packed_simd::u32x8;
|
|||
use crate::backend::vector::avx2::edwards::{CachedPoint, ExtendedPoint};
|
||||
use crate::backend::vector::avx2::field::FieldElement2625x4;
|
||||
|
||||
use crate::window::NafLookupTable5;
|
||||
#[cfg(feature = "precomputed-tables")]
|
||||
use crate::window::NafLookupTable8;
|
||||
|
||||
|
|
@ -37,6 +38,183 @@ pub(crate) static CACHEDPOINT_IDENTITY: CachedPoint = CachedPoint(FieldElement26
|
|||
u32x8::new_const(67108863, 0, 33554431, 0, 0, 67108863, 0, 33554431),
|
||||
]));
|
||||
|
||||
/// Odd multiples of `B * 2^128`, where `B` is the Ed25519 basepoint.
|
||||
pub(crate) static BASEPOINT_128_ODD_LOOKUP_TABLE: NafLookupTable5<CachedPoint> = NafLookupTable5([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
66534737, 44155216, 17527085, 25046477, 50454485, 25275908, 24427949, 19365218,
|
||||
),
|
||||
u32x8::new_const(
|
||||
15981845, 36873404, 8477272, 11176021, 40772245, 51234208, 6101715, 20397724,
|
||||
),
|
||||
u32x8::new_const(
|
||||
35665917, 53574296, 1951442, 2105772, 44081965, 9258257, 14333944, 20637141,
|
||||
),
|
||||
u32x8::new_const(
|
||||
16279886, 64719067, 15989606, 21668724, 19140425, 62032528, 31894001, 14000444,
|
||||
),
|
||||
u32x8::new_const(
|
||||
36500306, 17827321, 19052241, 838783, 31029387, 53863823, 8190087, 6168061,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
58297975, 1271791, 26327207, 12780927, 21326724, 55825376, 1881468, 19837539,
|
||||
),
|
||||
u32x8::new_const(
|
||||
41889841, 51572094, 29732198, 3211604, 26179218, 66326610, 23747079, 9590379,
|
||||
),
|
||||
u32x8::new_const(
|
||||
3826490, 25399835, 21583051, 18952539, 65295023, 42750425, 2246330, 32346254,
|
||||
),
|
||||
u32x8::new_const(
|
||||
52190758, 32188098, 24570211, 20678866, 40932593, 8178429, 27967937, 28257661,
|
||||
),
|
||||
u32x8::new_const(
|
||||
30236672, 9815342, 29650636, 24107060, 43660614, 37629440, 12674453, 2006553,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
61053967, 64436103, 447268, 25700182, 19255118, 14993526, 899478, 2434175,
|
||||
),
|
||||
u32x8::new_const(
|
||||
35812815, 10060004, 31384605, 25670757, 9561857, 60752897, 21085685, 27549514,
|
||||
),
|
||||
u32x8::new_const(
|
||||
18488525, 64357302, 10815830, 2935874, 29965756, 65776827, 18067405, 29757081,
|
||||
),
|
||||
u32x8::new_const(
|
||||
9151450, 55058906, 9505908, 19318842, 16283246, 36644461, 27208985, 12764280,
|
||||
),
|
||||
u32x8::new_const(
|
||||
935064, 62208992, 28617878, 9642406, 33296477, 20692366, 14092783, 29523038,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
43982257, 1870168, 4563592, 25651161, 16953299, 59521203, 32759146, 23740415,
|
||||
),
|
||||
u32x8::new_const(
|
||||
58238384, 34563808, 32443148, 21494201, 4125650, 52067840, 14679425, 9739512,
|
||||
),
|
||||
u32x8::new_const(
|
||||
22799713, 45658991, 31646134, 20985007, 25125757, 30914923, 23225832, 25549240,
|
||||
),
|
||||
u32x8::new_const(
|
||||
57964769, 17027909, 11726313, 16601782, 55202345, 44469180, 19529404, 17872655,
|
||||
),
|
||||
u32x8::new_const(
|
||||
29135281, 26779810, 23911498, 19293297, 15382461, 22625292, 27273113, 11918932,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
20356928, 44286797, 22416632, 26923729, 37256426, 26174151, 8631283, 13726744,
|
||||
),
|
||||
u32x8::new_const(
|
||||
15050322, 50131342, 17556728, 23214692, 57865782, 26708371, 14597005, 31489486,
|
||||
),
|
||||
u32x8::new_const(
|
||||
10930030, 52761167, 17112689, 22969526, 21350113, 19294179, 2468751, 28829631,
|
||||
),
|
||||
u32x8::new_const(
|
||||
21428704, 20303938, 30589121, 12662814, 5328394, 19277415, 17102411, 16988972,
|
||||
),
|
||||
u32x8::new_const(
|
||||
18480836, 42343373, 1078384, 27210912, 44126946, 66557826, 6700400, 7552628,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
26298451, 31358962, 2410750, 1222016, 6602808, 44151217, 19067066, 20265648,
|
||||
),
|
||||
u32x8::new_const(
|
||||
55489773, 8500419, 18022394, 14157663, 64952743, 30690464, 4133387, 4111644,
|
||||
),
|
||||
u32x8::new_const(
|
||||
62382671, 36329179, 8557628, 5794859, 23898950, 33060808, 8782720, 32408648,
|
||||
),
|
||||
u32x8::new_const(
|
||||
42610331, 38124770, 7134858, 18736387, 7942085, 52164416, 31680501, 29556327,
|
||||
),
|
||||
u32x8::new_const(
|
||||
5234530, 9444407, 25023918, 10390934, 8479340, 52612004, 32163536, 23949516,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
23655649, 20966851, 549747, 32424363, 65477828, 28514773, 964955, 24097969,
|
||||
),
|
||||
u32x8::new_const(
|
||||
10190745, 12573645, 17574436, 8670785, 40257066, 24017385, 18903364, 2903730,
|
||||
),
|
||||
u32x8::new_const(
|
||||
65255895, 6342458, 8253517, 21684439, 25311893, 11419775, 17555636, 8477305,
|
||||
),
|
||||
u32x8::new_const(
|
||||
28276837, 53282575, 15032193, 7864586, 13987263, 58062910, 14566708, 20452982,
|
||||
),
|
||||
u32x8::new_const(
|
||||
23280558, 4071800, 13973538, 14314990, 3800625, 49289684, 21965196, 25337015,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new_const(
|
||||
12346933, 43640065, 11294461, 3235676, 17615927, 5260789, 4540788, 21895087,
|
||||
),
|
||||
u32x8::new_const(
|
||||
24450060, 4710546, 4707754, 6116116, 59999924, 32574139, 18219955, 32529652,
|
||||
),
|
||||
u32x8::new_const(
|
||||
48787857, 56833627, 595516, 15964297, 18845497, 56029604, 13864576, 18463356,
|
||||
),
|
||||
u32x8::new_const(
|
||||
7335332, 5495540, 24018875, 1219221, 18695805, 51707846, 5336005, 18884320,
|
||||
),
|
||||
u32x8::new_const(
|
||||
27774957, 50806778, 32219720, 17063358, 30418813, 19859422, 2807745, 31952068,
|
||||
),
|
||||
])),
|
||||
]);
|
||||
|
||||
#[cfg(all(test, target_feature = "avx2"))]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::constants as curve_constants;
|
||||
|
||||
fn lanes(limb: u32x8) -> [u32; 8] {
|
||||
[
|
||||
limb.extract::<0>(),
|
||||
limb.extract::<1>(),
|
||||
limb.extract::<2>(),
|
||||
limb.extract::<3>(),
|
||||
limb.extract::<4>(),
|
||||
limb.extract::<5>(),
|
||||
limb.extract::<6>(),
|
||||
limb.extract::<7>(),
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basepoint_128_odd_lookup_table_matches_runtime_generation() {
|
||||
let runtime =
|
||||
NafLookupTable5::<CachedPoint>::from(&curve_constants::ED25519_BASEPOINT_128_POINT);
|
||||
|
||||
for (static_point, runtime_point) in BASEPOINT_128_ODD_LOOKUP_TABLE
|
||||
.0
|
||||
.iter()
|
||||
.zip(runtime.0.iter())
|
||||
{
|
||||
let static_field = &static_point.0;
|
||||
let runtime_field = &runtime_point.0;
|
||||
for (static_limb, runtime_limb) in static_field.0.iter().zip(runtime_field.0.iter()) {
|
||||
assert_eq!(lanes(*static_limb), lanes(*runtime_limb));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The low limbs of (2p, 2p, 2p, 2p), so that
|
||||
/// ```ascii,no_run
|
||||
/// (2p, 2p, 2p, 2p) = [P_TIMES_2_LO, P_TIMES_2_HI, P_TIMES_2_HI, P_TIMES_2_HI, P_TIMES_2_HI]
|
||||
|
|
|
|||
|
|
@ -15,10 +15,13 @@ pub mod spec {
|
|||
#[for_target_feature("avx2")]
|
||||
use crate::backend::vector::avx2::{CachedPoint, ExtendedPoint};
|
||||
|
||||
#[for_target_feature("avx2")]
|
||||
use crate::backend::vector::avx2::constants::BASEPOINT_128_ODD_LOOKUP_TABLE;
|
||||
#[cfg(feature = "precomputed-tables")]
|
||||
#[for_target_feature("avx2")]
|
||||
use crate::backend::vector::avx2::constants::BASEPOINT_ODD_LOOKUP_TABLE;
|
||||
|
||||
#[cfg(not(feature = "precomputed-tables"))]
|
||||
use crate::constants;
|
||||
use crate::edwards::EdwardsPoint;
|
||||
use crate::scalar::HEEA_MAX_INDEX;
|
||||
|
|
@ -111,10 +114,8 @@ pub mod spec {
|
|||
#[cfg(not(feature = "precomputed-tables"))]
|
||||
let table_B = &NafLookupTable5::<CachedPoint>::from(&constants::ED25519_BASEPOINT_POINT);
|
||||
|
||||
// B' = B * 2^128 (precomputed constant point)
|
||||
// TODO: For optimal performance, this should also use the wider lookup table when precomputed-tables is enabled
|
||||
let table_B_128 =
|
||||
&NafLookupTable5::<CachedPoint>::from(&constants::ED25519_BASEPOINT_128_POINT);
|
||||
// B' = B * 2^128.
|
||||
let table_B_128 = &BASEPOINT_128_ODD_LOOKUP_TABLE;
|
||||
|
||||
let mut Q = ExtendedPoint::identity();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue