mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
import mbedtls ecc point (de)compression extension and use
This commit is contained in:
parent
59aa95fa6e
commit
44f2e253d8
4 changed files with 237 additions and 5 deletions
130
common/mbedtls/ecc_point_compression.c
Normal file
130
common/mbedtls/ecc_point_compression.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Not original to the mbedtls library. Taken from
|
||||
* https://github.com/mwarning/mbedtls_ecp_compression
|
||||
* to solve mbedtls' lack of support for elliptic point
|
||||
* compression and decompression
|
||||
*
|
||||
* Released under CC0 1.0 Universal License
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is all about mbedtls_ecp_decompress() and mbedtls_ecp_compress()
|
||||
*
|
||||
* Perform X25519 / Curve25519 point compression and decompression for mbedtls.
|
||||
* As of mbedtls 2.5.1, mbedtls does not support decompression yet.
|
||||
*
|
||||
*/
|
||||
|
||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
|
||||
#include "ecc_point_compression.h"
|
||||
|
||||
int mbedtls_ecp_decompress(
|
||||
const mbedtls_ecp_group *grp,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize
|
||||
) {
|
||||
int ret;
|
||||
size_t plen;
|
||||
mbedtls_mpi r;
|
||||
mbedtls_mpi x;
|
||||
mbedtls_mpi n;
|
||||
|
||||
plen = mbedtls_mpi_size(&grp->P);
|
||||
|
||||
*olen = 2 * plen + 1;
|
||||
|
||||
if (osize < *olen)
|
||||
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
|
||||
|
||||
if (ilen != plen + 1)
|
||||
return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||
|
||||
if (input[0] != 0x02 && input[0] != 0x03)
|
||||
return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||
|
||||
// output will consist of 0x04|X|Y
|
||||
memcpy(output, input, ilen);
|
||||
output[0] = 0x04;
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&x);
|
||||
mbedtls_mpi_init(&n);
|
||||
|
||||
// x <= input
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&x, input + 1, plen));
|
||||
|
||||
// r = x^2
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &x, &x));
|
||||
|
||||
// r = x^2 + a
|
||||
if (grp->A.p == NULL) {
|
||||
// Special case where a is -3
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&r, &r, 3));
|
||||
} else {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->A));
|
||||
}
|
||||
|
||||
// r = x^3 + ax
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &r, &x));
|
||||
|
||||
// r = x^3 + ax + b
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->B));
|
||||
|
||||
// Calculate square root of r over finite field P:
|
||||
// r = sqrt(x^3 + ax + b) = (x^3 + ax + b) ^ ((P + 1) / 4) (mod P)
|
||||
|
||||
// n = P + 1
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&n, &grp->P, 1));
|
||||
|
||||
// n = (P + 1) / 4
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&n, 2));
|
||||
|
||||
// r ^ ((P + 1) / 4) (mod p)
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r, &r, &n, &grp->P, NULL));
|
||||
|
||||
// Select solution that has the correct "sign" (equals odd/even solution in finite group)
|
||||
if ((input[0] == 0x03) != mbedtls_mpi_get_bit(&r, 0)) {
|
||||
// r = p - r
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&r, &grp->P, &r));
|
||||
}
|
||||
|
||||
// y => output
|
||||
ret = mbedtls_mpi_write_binary(&r, output + 1 + plen, plen);
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&x);
|
||||
mbedtls_mpi_free(&n);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int mbedtls_ecp_compress(
|
||||
const mbedtls_ecp_group *grp,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize
|
||||
) {
|
||||
size_t plen;
|
||||
|
||||
plen = mbedtls_mpi_size(&grp->P);
|
||||
|
||||
*olen = plen + 1;
|
||||
|
||||
if (osize < *olen)
|
||||
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
|
||||
|
||||
if (ilen != 2 * plen + 1)
|
||||
return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||
|
||||
if (input[0] != 0x04)
|
||||
return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||
|
||||
// output will consist of 0x0?|X
|
||||
memcpy(output, input, *olen);
|
||||
|
||||
// Encode even/odd of Y into first byte (either 0x02 or 0x03)
|
||||
output[0] = 0x02 + (input[2 * plen] & 1);
|
||||
|
||||
return(0);
|
||||
}
|
32
common/mbedtls/ecc_point_compression.h
Normal file
32
common/mbedtls/ecc_point_compression.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Not original to the mbedtls library. Taken from
|
||||
* https://github.com/mwarning/mbedtls_ecp_compression
|
||||
* to solve mbedtls' lack of support for elliptic point
|
||||
* compression and decompression
|
||||
*
|
||||
* Released under CC0 1.0 Universal License
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is all about mbedtls_ecp_decompress() and mbedtls_ecp_compress()
|
||||
*
|
||||
* Perform X25519 / Curve25519 point compression and decompression for mbedtls.
|
||||
* As of mbedtls 2.5.1, mbedtls does not support decompression yet.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
int mbedtls_ecp_decompress(
|
||||
const mbedtls_ecp_group *grp,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize
|
||||
);
|
||||
|
||||
int mbedtls_ecp_compress(
|
||||
const mbedtls_ecp_group *grp,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue