forked from xuos/xiuos
158 lines
4.1 KiB
C
Executable File
158 lines
4.1 KiB
C
Executable File
/*
|
|
* Copyright (c) 2020 AIIT Ubiquitous Team
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
|
|
/**
|
|
* @file ecc.c
|
|
* @brief arithmetic in ecc
|
|
* @version 1.0
|
|
* @author AIIT Ubiquitous Team
|
|
* @date 2021-04-24
|
|
*/
|
|
#include <ecc.h>
|
|
|
|
/**
|
|
* @brief Print the point(x, y)
|
|
*
|
|
* @param point pointer of a point in group G1.
|
|
*
|
|
* @return null
|
|
*/
|
|
void G1pointPrint(G1point *point)
|
|
{
|
|
Big8wPrint(&point->x);
|
|
Big8wPrint(&point->y);
|
|
}
|
|
/**
|
|
* @brief judge whether the point in group G1
|
|
*
|
|
* @param point a point(x, y)
|
|
*
|
|
* @return true if point in group G1; else false
|
|
*
|
|
*/
|
|
bool PointInG1(G1point point)
|
|
{
|
|
big8w y_power2;
|
|
big8w temp;
|
|
|
|
y_power2 = Big8wMultMod(point.y, point.y, curve.q); // y^2 mod curve.q
|
|
|
|
temp = Big8wMultMod(point.x, point.x, curve.q);
|
|
temp = Big8wMultMod(temp, point.x, curve.q); // x^3
|
|
|
|
temp = Big8wAddMod(temp, curve.b, curve.q); // x^3 + b
|
|
|
|
return Big8wEqual(&y_power2, &temp);
|
|
}
|
|
/**
|
|
*
|
|
* @brief compute the sum of two points in group G1; set infinite point O as (0, 0), tell if exist O before points add.
|
|
* Calls: big8wIszero, Big8wEqual, Big8wAddMod, Big8wMinusMod, Big8wReverse
|
|
* Called By: G1pointMult
|
|
*
|
|
* @param point1 the first point in group G1
|
|
* @param point2 the second point in group G1
|
|
*
|
|
* @return a point in group
|
|
*
|
|
*/
|
|
G1point G1pointAdd(G1point point1, G1point point2)
|
|
{
|
|
G1point ret;
|
|
big8w lambda, temp;
|
|
|
|
// infinite point
|
|
if (Big8wIsZero(&point1.x) && Big8wIsZero(&point1.y))
|
|
return point2;
|
|
else if (Big8wIsZero(&point1.x) && Big8wIsZero(&point1.y))
|
|
return point1;
|
|
|
|
if (Big8wEqual(&point1.x, &point2.x)) {
|
|
|
|
if (!Big8wEqual(&point1.y, &point2.y)){ // x1=x2, y1 != y2(y1 = -y2), ret = O (0, 0)
|
|
memset(ret.x.word, 0x00, BIG8W_BYTESIZE);
|
|
memset(ret.y.word, 0x00, BIG8W_BYTESIZE);
|
|
return ret;
|
|
}
|
|
|
|
temp = Big8wAddMod(point1.y, point1.y, curve.q); // 2*y1
|
|
temp = Big8wReverse(temp, curve.q); // 1/2*y1
|
|
temp = Big8wMultMod(point1.x, temp, curve.q); // x1*(1/2*y1)
|
|
temp = Big8wMultMod(point1.x, temp, curve.q); // x1*x1*(1/2*y1)
|
|
lambda = Big8wAddMod(temp, Big8wAddMod(temp, temp, curve.q), curve.q); // 3*x1*x1*(1/2*y1)
|
|
}
|
|
else {
|
|
temp = Big8wMinusMod(point1.x, point2.x, curve.q);
|
|
temp = Big8wReverse(temp, curve.q); // 1/(x2 - x1)
|
|
|
|
lambda = Big8wMinusMod(point1.y, point2.y, curve.q); // y2 - y1
|
|
lambda = Big8wMultMod(temp, lambda, curve.q);
|
|
}
|
|
|
|
ret.x = Big8wMultMod(lambda, lambda, curve.q); // k*k
|
|
temp = Big8wAddMod(point1.x, point2.x, curve.q); // x1 + x2
|
|
ret.x = Big8wMinusMod(ret.x, temp, curve.q); // x3 = lambda*lambda - x1 - x2
|
|
|
|
ret.y = Big8wMinusMod(point1.x, ret.x, curve.q); // y3 = lambda*(x1 - x3) - y1
|
|
ret.y = Big8wMultMod(lambda, ret.y, curve.q);
|
|
ret.y = Big8wMinusMod(ret.y, point1.y, curve.q);
|
|
|
|
return ret;
|
|
}
|
|
/**
|
|
*
|
|
* @brief mult point; scan bits of bignum
|
|
*
|
|
* @param bignum big number, bignum > 0
|
|
* @param point point in group G1
|
|
*
|
|
* @return a point in group G1
|
|
*
|
|
*/
|
|
// could optimized by scan the segment of continuous 1.
|
|
G1point G1pointMult(big8w bignum, G1point point)
|
|
{
|
|
bool flag = 0;
|
|
int i = BIGNUMBER_SIZE_8WORD - 1;
|
|
int index = Big8wHighestbit(&bignum);
|
|
uint32_t elem;
|
|
G1point ret = point;
|
|
G1point temp = point;
|
|
|
|
while (bignum.word[i] == 0)
|
|
i--;
|
|
elem = bignum.word[i];
|
|
|
|
index--;
|
|
while (index>=0) {
|
|
flag = (elem >> (index--)) & 1;
|
|
ret = G1pointAdd(temp, temp);
|
|
if (flag)
|
|
ret = G1pointAdd(ret, point);
|
|
temp = ret;
|
|
}
|
|
|
|
i--;
|
|
for (; i>=0; i--) {
|
|
elem = bignum.word[i];
|
|
index = 31;
|
|
while (index>=0) {
|
|
flag = (elem >> (index--)) & 1;
|
|
ret = G1pointAdd(temp, temp);
|
|
if (flag)
|
|
ret = G1pointAdd(ret, point);
|
|
temp = ret;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
} |