xiuos/APP_Framework/Framework/security/crypto/sm9/ecc.c

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;
}