Skip to content

Commit

Permalink
ec: implement P521 signature verification
Browse files Browse the repository at this point in the history
This code almost entirely reuses the P384 code, and only implements
the dedicated inversion routines.
  • Loading branch information
vkrasnov committed Oct 6, 2023
1 parent 28a970e commit 5664a87
Show file tree
Hide file tree
Showing 15 changed files with 1,724 additions and 15 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ include = [
"crypto/fipsmodule/ec/ecp_nistz.inl",
"crypto/fipsmodule/ec/gfp_p256.c",
"crypto/fipsmodule/ec/gfp_p384.c",
"crypto/fipsmodule/ec/gfp_p521.c",
"crypto/fipsmodule/ec/p256.c",
"crypto/fipsmodule/ec/p256-nistz-table.h",
"crypto/fipsmodule/ec/p256-nistz.c",
Expand Down
9 changes: 9 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[
(&[], "crypto/fipsmodule/ec/ecp_nistz.c"),
(&[], "crypto/fipsmodule/ec/gfp_p256.c"),
(&[], "crypto/fipsmodule/ec/gfp_p384.c"),
(&[], "crypto/fipsmodule/ec/gfp_p521.c"),
(&[], "crypto/fipsmodule/ec/p256.c"),
(&[], "crypto/limbs/limbs.c"),
(&[], "crypto/mem.c"),
Expand Down Expand Up @@ -983,6 +984,9 @@ fn prefix_all_symbols(pp: char, prefix_prefix: &str, prefix: &str) -> String {
"nistz384_point_add",
"nistz384_point_double",
"nistz384_point_mul",
"nistz521_point_add",
"nistz521_point_double",
"nistz521_point_mul",
"p256_mul_mont",
"p256_point_add",
"p256_point_add_affine",
Expand All @@ -997,6 +1001,11 @@ fn prefix_all_symbols(pp: char, prefix_prefix: &str, prefix: &str) -> String {
"p384_elem_neg",
"p384_elem_sub",
"p384_scalar_mul_mont",
"p521_elem_div_by_2",
"p521_elem_mul_mont",
"p521_elem_neg",
"p521_elem_sub",
"p521_scalar_mul_mont",
"openssl_poly1305_neon2_addmulmod",
"openssl_poly1305_neon2_blocks",
"sha256_block_data_order",
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/ec/ecp_nistz.inl
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ void point_mul(BITS)(NIST_POINT *r, const BN_ULONG p_scalar[FE_LIMBS],
}

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

BN_ULONG recoded_is_negative;
Expand Down
122 changes: 122 additions & 0 deletions crypto/fipsmodule/ec/gfp_p521.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* Copyright 2016 Brian Smith.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "../../limbs/limbs.h"

#include "../bn/internal.h"
#include "../../internal.h"

#include "../../limbs/limbs.inl"

#define P521_LIMBS ((521u + LIMB_BITS - 1u)/ LIMB_BITS)
#if defined(OPENSSL_64_BIT)

static const BN_ULONG Q[P521_LIMBS] = {
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff, 0x00000000000001ff
};

static const BN_ULONG N[P521_LIMBS] = {
0xbb6fb71e91386409, 0x3bb5c9b8899c47ae, 0x7fcc0148f709a5d0,
0x51868783bf2f966b, 0xfffffffffffffffa, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff, 0x00000000000001ff
};

static const BN_ULONG ONE[P521_LIMBS] = {
0x0080000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000
};

/* This is just 2**520 */
static const BN_ULONG Q_PLUS_1_SHR_1[P521_LIMBS] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000100
};

#elif defined(OPENSSL_32_BIT)

static const BN_ULONG Q[P521_LIMBS] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff
};

static const BN_ULONG N[P521_LIMBS] = {
0x91386409, 0xbb6fb71e, 0x899c47ae, 0x3bb5c9b8, 0xf709a5d0, 0x7fcc0148,
0xbf2f966b, 0x51868783, 0xfffffffa, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff
};

static const BN_ULONG ONE[P521_LIMBS] = {
0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
};

static const BN_ULONG Q_PLUS_1_SHR_1[P521_LIMBS] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100
};

#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif

static const BN_ULONG Q_N0[] = {
BN_MONT_CTX_N0(0x0, 0x1)
};

/* XXX: MSVC for x86 warns when it fails to inline these functions it should
* probably inline. */
#if defined(_MSC_VER) && !defined(__clang__) && defined(OPENSSL_X86)
#define INLINE_IF_POSSIBLE __forceinline
#else
#define INLINE_IF_POSSIBLE inline
#endif

#define BITS 521
/* Window values that are Ok for p521 (look at `ecp_nistz.h`): 4 */
#define W_BITS 4
#define FE_LIMBS P521_LIMBS

#include "ecp_nistz.inl"

void p521_elem_sub(Elem r, const Elem a, const Elem b) {
elem_sub(r, a, b);
}

Check warning on line 101 in crypto/fipsmodule/ec/gfp_p521.c

View check run for this annotation

Codecov / codecov/patch

crypto/fipsmodule/ec/gfp_p521.c#L99-L101

Added lines #L99 - L101 were not covered by tests

void p521_elem_div_by_2(Elem r, const Elem a) {
elem_div_by_2(r, a);
}

Check warning on line 105 in crypto/fipsmodule/ec/gfp_p521.c

View check run for this annotation

Codecov / codecov/patch

crypto/fipsmodule/ec/gfp_p521.c#L103-L105

Added lines #L103 - L105 were not covered by tests

void p521_elem_mul_mont(Elem r, const Elem a, const Elem b) {
elem_mul_mont(r, a, b);
}

void p521_elem_neg(Elem r, const Elem a) {
elem_neg(r, a);
}

Check warning on line 113 in crypto/fipsmodule/ec/gfp_p521.c

View check run for this annotation

Codecov / codecov/patch

crypto/fipsmodule/ec/gfp_p521.c#L111-L113

Added lines #L111 - L113 were not covered by tests

void p521_scalar_mul_mont(ScalarMont r, const ScalarMont a,
const ScalarMont b) {
static const BN_ULONG N_N0[] = {
BN_MONT_CTX_N0(0x1d2f5ccd, 0x79a995c7)
};
/* XXX: Inefficient. TODO: Add dedicated multiplication routine. */
bn_mul_mont(r, a, b, N, N_N0, FE_LIMBS);
}
Loading

0 comments on commit 5664a87

Please sign in to comment.