Network wrapper protocol as part of the practical master thesis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

159 lines
4.9 KiB

/******************************************************************************
*
* Copyright 2017 Xaptum, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*
*****************************************************************************/
#include "./ecp_FP256BN.h"
#include "./big_256_56.h"
#include "internal-utilities/rand_pool.h"
size_t ecp_FP256BN_length(void)
{
return ECP_FP256BN_LENGTH;
}
void ecp_FP256BN_set_to_generator(ECP_FP256BN *point)
{
BIG_256_56 gx, gy;
BIG_256_56_rcopy(gx, CURVE_Gx_FP256BN);
BIG_256_56_rcopy(gy, CURVE_Gy_FP256BN);
(void)ECP_FP256BN_set(point, gx, gy); // we know this will succeed, b/c the coords are for the generator
}
void ecp_FP256BN_serialize(uint8_t *buffer_out,
ECP_FP256BN *point)
{
octet as_oct = {.len = 0,
.max = ECP_FP256BN_LENGTH,
.val = (char*)buffer_out};
ECP_FP256BN_toOctet(&as_oct, point);
}
int ecp_FP256BN_deserialize(ECP_FP256BN *point_out,
uint8_t *buffer)
{
// 1) Check that serialized point was properly formatted.
if (0x4 != buffer[0])
return -2;
// 2) Get the x,y coordinates.
BIG_256_56 wx, wy;
BIG_256_56_fromBytes(wx, (char*)&(buffer[1]));
BIG_256_56_fromBytes(wy, (char*)&(buffer[MODBYTES_256_56+1]));
// 3) Check the coordinates are valid Fp points
// (i.e. that they are less-than modulus)
// (step 2 in X9.62 Sec 5.2.2)
BIG_256_56 q;
BIG_256_56_rcopy(q, Modulus_FP256BN);
if (1 == BIG_256_56_comp(wx, q))
return -1;
if (1 == BIG_256_56_comp(wy, q))
return -1;
// 4) Check that point is on curve (ECP_FP256BN_set does this implicitly).
// (step 3 in X9.62 Sec 5.2.2)
if (!ECP_FP256BN_set(point_out, wx, wy)) {
return -1;
}
// 5) Check that point is not the identity.
// (step 1 in X9.62 Sec 5.2.2)
if (ECP_FP256BN_isinf(point_out)) {
return -1;
}
// 6) Check that point is in the proper subgroup
// (step 4 in X9.62 Sec 5.2.2)
// (order*point == inf is equivalent to cofactor*point != inf).
ECP_FP256BN point_copy;
ECP_FP256BN_copy(&point_copy, point_out);
BIG_256_56 cof;
BIG_256_56_rcopy(cof, CURVE_Cof_FP256BN);
ECP_FP256BN_mul(&point_copy, cof);
if (ECP_FP256BN_isinf(&point_copy)) {
return -1;
}
return 0;
}
int32_t ecp_FP256BN_fromhash(ECP_FP256BN *point_out, const uint8_t *message, uint32_t message_length)
{
// Following the Appendix of Chen and Li, 2013
BIG_256_56 curve_order;
BIG_256_56_rcopy(curve_order, CURVE_Order_FP256BN);
for (int32_t i=0; i < 232; i++) {
BIG_256_56 x;
big_256_56_from_two_message_hash(&x, (uint8_t*)&i, sizeof(i), message, message_length);
BIG_256_56_mod(x, curve_order);
// Check if generated point is on curve:
// (the 0 indicates we want the y-coord with lsb=0)
if (ECP_FP256BN_setx(point_out, x, 0)) {
// If on curve, and cofactor != 1, multiply by cofactor to get on correct subgroup.
BIG_256_56 cofactor;
BIG_256_56_rcopy(cofactor, CURVE_Cof_FP256BN);
if (!BIG_256_56_isunity(cofactor)) {
ECP_FP256BN_mul(point_out, cofactor);
}
return i;
}
}
// If we reach here, we ran out of tries, so return error.
return -1;
}
void ecp_FP256BN_random_mod_order(BIG_256_56 *big_out,
void (*get_random)(void *buf, size_t buflen))
{
// 1) Get the order of the group
BIG_256_56 curve_order;
BIG_256_56_rcopy(curve_order, CURVE_Order_FP256BN);
// 2) Initialize our randomness
struct ecdaa_rand_pool rand_pool;
size_t needed_random_bytes = (size_t)(1 + 2*BIG_256_56_nbits(curve_order) / 8);
ecdaa_rand_pool_init(&rand_pool, needed_random_bytes, get_random);
// 3) Generate a random BIG bit-by-bit,
// then reduce it modulo the group order.
// Adapted from AMCL big.c.in::BIG_256_56_randomnum() function
int i,j=0;
uint8_t r=0;
DBIG_256_56 d;
BIG_256_56_dzero(d);
/* generate random DBIG */
for (i=0; i<2*BIG_256_56_nbits(curve_order); i++)
{
if (j==0) r=get_random_byte(&rand_pool);
else r>>=1;
int b=r&1;
BIG_256_56_dshl(d,1);
d[0]+=b;
j++;
j&=7;
}
/* reduce modulo a BIG. Removes bias */
BIG_256_56_dmod(*big_out,d,curve_order);
}