Skip to content

Commit 5664a87

Browse files
committed
ec: implement P521 signature verification
This code almost entirely reuses the P384 code, and only implements the dedicated inversion routines.
1 parent 28a970e commit 5664a87

File tree

15 files changed

+1724
-15
lines changed

15 files changed

+1724
-15
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ include = [
7272
"crypto/fipsmodule/ec/ecp_nistz.inl",
7373
"crypto/fipsmodule/ec/gfp_p256.c",
7474
"crypto/fipsmodule/ec/gfp_p384.c",
75+
"crypto/fipsmodule/ec/gfp_p521.c",
7576
"crypto/fipsmodule/ec/p256.c",
7677
"crypto/fipsmodule/ec/p256-nistz-table.h",
7778
"crypto/fipsmodule/ec/p256-nistz.c",

build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[
4141
(&[], "crypto/fipsmodule/ec/ecp_nistz.c"),
4242
(&[], "crypto/fipsmodule/ec/gfp_p256.c"),
4343
(&[], "crypto/fipsmodule/ec/gfp_p384.c"),
44+
(&[], "crypto/fipsmodule/ec/gfp_p521.c"),
4445
(&[], "crypto/fipsmodule/ec/p256.c"),
4546
(&[], "crypto/limbs/limbs.c"),
4647
(&[], "crypto/mem.c"),
@@ -983,6 +984,9 @@ fn prefix_all_symbols(pp: char, prefix_prefix: &str, prefix: &str) -> String {
983984
"nistz384_point_add",
984985
"nistz384_point_double",
985986
"nistz384_point_mul",
987+
"nistz521_point_add",
988+
"nistz521_point_double",
989+
"nistz521_point_mul",
986990
"p256_mul_mont",
987991
"p256_point_add",
988992
"p256_point_add_affine",
@@ -997,6 +1001,11 @@ fn prefix_all_symbols(pp: char, prefix_prefix: &str, prefix: &str) -> String {
9971001
"p384_elem_neg",
9981002
"p384_elem_sub",
9991003
"p384_scalar_mul_mont",
1004+
"p521_elem_div_by_2",
1005+
"p521_elem_mul_mont",
1006+
"p521_elem_neg",
1007+
"p521_elem_sub",
1008+
"p521_scalar_mul_mont",
10001009
"openssl_poly1305_neon2_addmulmod",
10011010
"openssl_poly1305_neon2_blocks",
10021011
"sha256_block_data_order",

crypto/fipsmodule/ec/ecp_nistz.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ void point_mul(BITS)(NIST_POINT *r, const BN_ULONG p_scalar[FE_LIMBS],
362362
}
363363

364364
static const size_t ROUND_SIZE = (BITS + W_BITS - 1) / W_BITS * W_BITS;
365-
static const size_t START_INDEX = ROUND_SIZE == BITS + 1 ? ROUND_SIZE - W_BITS: ROUND_SIZE;
365+
size_t START_INDEX = ROUND_SIZE == BITS + 1 ? ROUND_SIZE - W_BITS: ROUND_SIZE;
366366
size_t index = START_INDEX;
367367

368368
BN_ULONG recoded_is_negative;

crypto/fipsmodule/ec/gfp_p521.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/* Copyright 2016 Brian Smith.
2+
*
3+
* Permission to use, copy, modify, and/or distribute this software for any
4+
* purpose with or without fee is hereby granted, provided that the above
5+
* copyright notice and this permission notice appear in all copies.
6+
*
7+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10+
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12+
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14+
15+
#include "../../limbs/limbs.h"
16+
17+
#include "../bn/internal.h"
18+
#include "../../internal.h"
19+
20+
#include "../../limbs/limbs.inl"
21+
22+
#define P521_LIMBS ((521u + LIMB_BITS - 1u)/ LIMB_BITS)
23+
#if defined(OPENSSL_64_BIT)
24+
25+
static const BN_ULONG Q[P521_LIMBS] = {
26+
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
27+
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
28+
0xffffffffffffffff, 0xffffffffffffffff, 0x00000000000001ff
29+
};
30+
31+
static const BN_ULONG N[P521_LIMBS] = {
32+
0xbb6fb71e91386409, 0x3bb5c9b8899c47ae, 0x7fcc0148f709a5d0,
33+
0x51868783bf2f966b, 0xfffffffffffffffa, 0xffffffffffffffff,
34+
0xffffffffffffffff, 0xffffffffffffffff, 0x00000000000001ff
35+
};
36+
37+
static const BN_ULONG ONE[P521_LIMBS] = {
38+
0x0080000000000000, 0x0000000000000000, 0x0000000000000000,
39+
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
40+
0x0000000000000000, 0x0000000000000000, 0x0000000000000000
41+
};
42+
43+
/* This is just 2**520 */
44+
static const BN_ULONG Q_PLUS_1_SHR_1[P521_LIMBS] = {
45+
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
46+
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
47+
0x0000000000000000, 0x0000000000000000, 0x0000000000000100
48+
};
49+
50+
#elif defined(OPENSSL_32_BIT)
51+
52+
static const BN_ULONG Q[P521_LIMBS] = {
53+
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
54+
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
55+
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff
56+
};
57+
58+
static const BN_ULONG N[P521_LIMBS] = {
59+
0x91386409, 0xbb6fb71e, 0x899c47ae, 0x3bb5c9b8, 0xf709a5d0, 0x7fcc0148,
60+
0xbf2f966b, 0x51868783, 0xfffffffa, 0xffffffff, 0xffffffff, 0xffffffff,
61+
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff
62+
};
63+
64+
static const BN_ULONG ONE[P521_LIMBS] = {
65+
0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66+
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
67+
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
68+
};
69+
70+
static const BN_ULONG Q_PLUS_1_SHR_1[P521_LIMBS] = {
71+
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
72+
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
73+
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100
74+
};
75+
76+
#else
77+
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
78+
#endif
79+
80+
static const BN_ULONG Q_N0[] = {
81+
BN_MONT_CTX_N0(0x0, 0x1)
82+
};
83+
84+
/* XXX: MSVC for x86 warns when it fails to inline these functions it should
85+
* probably inline. */
86+
#if defined(_MSC_VER) && !defined(__clang__) && defined(OPENSSL_X86)
87+
#define INLINE_IF_POSSIBLE __forceinline
88+
#else
89+
#define INLINE_IF_POSSIBLE inline
90+
#endif
91+
92+
#define BITS 521
93+
/* Window values that are Ok for p521 (look at `ecp_nistz.h`): 4 */
94+
#define W_BITS 4
95+
#define FE_LIMBS P521_LIMBS
96+
97+
#include "ecp_nistz.inl"
98+
99+
void p521_elem_sub(Elem r, const Elem a, const Elem b) {
100+
elem_sub(r, a, b);
101+
}
102+
103+
void p521_elem_div_by_2(Elem r, const Elem a) {
104+
elem_div_by_2(r, a);
105+
}
106+
107+
void p521_elem_mul_mont(Elem r, const Elem a, const Elem b) {
108+
elem_mul_mont(r, a, b);
109+
}
110+
111+
void p521_elem_neg(Elem r, const Elem a) {
112+
elem_neg(r, a);
113+
}
114+
115+
void p521_scalar_mul_mont(ScalarMont r, const ScalarMont a,
116+
const ScalarMont b) {
117+
static const BN_ULONG N_N0[] = {
118+
BN_MONT_CTX_N0(0x1d2f5ccd, 0x79a995c7)
119+
};
120+
/* XXX: Inefficient. TODO: Add dedicated multiplication routine. */
121+
bn_mul_mont(r, a, b, N, N_N0, FE_LIMBS);
122+
}

0 commit comments

Comments
 (0)