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