-
-
Save flying-fury/6bc42c8bb60e5ea26631 to your computer and use it in GitHub Desktop.
Read compressed point with polarssl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "polarssl/ecp.h" | |
#include <stdio.h> | |
static const unsigned char comp[4][33] = { | |
{ 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, | |
{ 0x03, 0xF2, 0x87, 0x73, 0xC2, 0xD9, 0x75, 0x28, 0x8B, 0xC7, 0xD1, 0xD2, 0x05, 0xC3, 0x74, 0x86, 0x51, 0xB0, 0x75, 0xFB, 0xC6, 0x61, 0x0E, 0x58, 0xCD, 0xDE, 0xED, 0xDF, 0x8F, 0x19, 0x40, 0x5A, 0xA8 }, | |
{ 0x02, 0xFE, 0x8D, 0x1E, 0xB1, 0xBC, 0xB3, 0x43, 0x2B, 0x1D, 0xB5, 0x83, 0x3F, 0xF5, 0xF2, 0x22, 0x6D, 0x9C, 0xB5, 0xE6, 0x5C, 0xEE, 0x43, 0x05, 0x58, 0xC1, 0x8E, 0xD3, 0xA3, 0xC8, 0x6C, 0xE1, 0xAF }, | |
{ 0x03, 0x07, 0x92, 0x64, 0xC4, 0xB4, 0xBF, 0xCD, 0x7F, 0xE3, 0xA7, 0xB7, 0xB9, 0x2B, 0x6C, 0x43, 0x9F, 0x3A, 0x5B, 0x3A, 0xBC, 0xD2, 0x91, 0x89, 0xBF, 0x7B, 0x54, 0xD7, 0x81, 0xFF, 0x03, 0xD7, 0x22 } | |
}; | |
static const unsigned char uncomp[4][65] = { | |
{ 0x04, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8 }, | |
{ 0x04, 0xF2, 0x87, 0x73, 0xC2, 0xD9, 0x75, 0x28, 0x8B, 0xC7, 0xD1, 0xD2, 0x05, 0xC3, 0x74, 0x86, 0x51, 0xB0, 0x75, 0xFB, 0xC6, 0x61, 0x0E, 0x58, 0xCD, 0xDE, 0xED, 0xDF, 0x8F, 0x19, 0x40, 0x5A, 0xA8, 0x0A, 0xB0, 0x90, 0x2E, 0x8D, 0x88, 0x0A, 0x89, 0x75, 0x82, 0x12, 0xEB, 0x65, 0xCD, 0xAF, 0x47, 0x3A, 0x1A, 0x06, 0xDA, 0x52, 0x1F, 0xA9, 0x1F, 0x29, 0xB5, 0xCB, 0x52, 0xDB, 0x03, 0xED, 0x81 }, | |
{ 0x04, 0xFE, 0x8D, 0x1E, 0xB1, 0xBC, 0xB3, 0x43, 0x2B, 0x1D, 0xB5, 0x83, 0x3F, 0xF5, 0xF2, 0x22, 0x6D, 0x9C, 0xB5, 0xE6, 0x5C, 0xEE, 0x43, 0x05, 0x58, 0xC1, 0x8E, 0xD3, 0xA3, 0xC8, 0x6C, 0xE1, 0xAF, 0x07, 0xB1, 0x58, 0xF2, 0x44, 0xCD, 0x0D, 0xE2, 0x13, 0x4A, 0xC7, 0xC1, 0xD3, 0x71, 0xCF, 0xFB, 0xFA, 0xE4, 0xDB, 0x40, 0x80, 0x1A, 0x25, 0x72, 0xE5, 0x31, 0xC5, 0x73, 0xCD, 0xA9, 0xB5, 0xB4 }, | |
{ 0x04, 0x07, 0x92, 0x64, 0xC4, 0xB4, 0xBF, 0xCD, 0x7F, 0xE3, 0xA7, 0xB7, 0xB9, 0x2B, 0x6C, 0x43, 0x9F, 0x3A, 0x5B, 0x3A, 0xBC, 0xD2, 0x91, 0x89, 0xBF, 0x7B, 0x54, 0xD7, 0x81, 0xFF, 0x03, 0xD7, 0x22, 0x6F, 0x6F, 0x0E, 0x07, 0x84, 0xEA, 0xDA, 0x9F, 0x92, 0x99, 0x9E, 0xE9, 0xC4, 0x38, 0xD4, 0x7E, 0xAA, 0x2C, 0x80, 0x68, 0xF1, 0x84, 0x51, 0x97, 0xE3, 0x07, 0x1C, 0x74, 0xB0, 0x63, 0xC5, 0xE1 } | |
}; | |
// Single purpose read point in binary format, only support compressed secp256k1 point | |
int ecp_point_read_binary2(const ecp_group *group, ecp_point *point, const unsigned char *buffer, size_t ilen) { | |
int ret; | |
unsigned char parity; | |
size_t plen; | |
mpi e, y2; | |
mpi_init(&e); mpi_init(&y2); | |
ret = ecp_point_read_binary(group, point, buffer, ilen); | |
if (POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE != ret) { | |
return ret; | |
} | |
if (POLARSSL_ECP_DP_SECP256K1 != group->id) { | |
return POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE; | |
} | |
if (0x02 == buffer[0]) { | |
parity = 0; | |
} else if (0x03 == buffer[0]) { | |
parity = 1; | |
} else { | |
return POLARSSL_ERR_ECP_BAD_INPUT_DATA; | |
} | |
plen = mpi_size(&group->P); | |
if (ilen != plen + 1) { | |
return POLARSSL_ERR_ECP_BAD_INPUT_DATA; | |
} | |
MPI_CHK(mpi_read_binary(&point->X, buffer + 1, plen)); | |
MPI_CHK(mpi_lset(&point->Z, 1)); | |
// Set y2 = X^3 + B | |
MPI_CHK(mpi_mul_mpi(&y2, &point->X, &point->X)); | |
MPI_CHK(mpi_mod_mpi(&y2, &y2, &group->P)); | |
MPI_CHK(mpi_mul_mpi(&y2, &y2, &point->X)); | |
MPI_CHK(mpi_add_mpi(&y2, &y2, &group->B)); | |
MPI_CHK(mpi_mod_mpi(&y2, &y2, &group->P)); | |
// Compute square root of y2 | |
MPI_CHK(mpi_add_int(&e, &group->P, 1)); | |
MPI_CHK(mpi_shift_r(&e, 2)); | |
MPI_CHK(mpi_exp_mod(&point->Y, &y2, &e, &group->P, NULL)); | |
// Set parity | |
if (mpi_get_bit(&point->Y, 0) != parity) { | |
MPI_CHK(mpi_sub_mpi(&point->Y, &group->P, &point->Y)); | |
} | |
cleanup: | |
mpi_free(&e); | |
mpi_free(&y2); | |
return ret; | |
} | |
int main() { | |
int ret; | |
ecp_group group; | |
ecp_point point; | |
unsigned char buffer[65]; | |
size_t i, olen = 0; | |
ecp_group_init(&group); | |
ecp_point_init(&point); | |
MPI_CHK(ecp_use_known_dp(&group, POLARSSL_ECP_DP_SECP256K1)); | |
for (i = 0; i < 4; i++) { | |
MPI_CHK(ecp_point_read_binary2(&group, &point, comp[i], sizeof(comp[i]))); | |
MPI_CHK(ecp_point_write_binary(&group, &point, POLARSSL_ECP_PF_UNCOMPRESSED, &olen, buffer, sizeof(buffer))); | |
if (memcmp(buffer, uncomp[i], sizeof(buffer))) { | |
printf ("Failed. Point %d not same\n", i); | |
} else { | |
printf ("Point %d OK\n", i); | |
} | |
ecp_point_free(&point); | |
} | |
cleanup: | |
ecp_group_free(&group); | |
ecp_point_free(&point); | |
if (ret) { | |
printf("failed: -0x%04X\n", -ret); | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment