add sm3 sm4 sm9 crypto algorithm
This commit is contained in:
parent
9fb9a3a2ec
commit
e012005b45
|
@ -1,3 +1,3 @@
|
|||
SRC_DIR := connection perception intelligent
|
||||
SRC_DIR := connection perception intelligent security
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
menu "Security"
|
||||
|
||||
menuconfig CRYPTO
|
||||
bool "using crypto"
|
||||
default n
|
||||
if CRYPTO
|
||||
menuconfig CRYPTO_SM3
|
||||
bool "using sm3"
|
||||
default n
|
||||
|
||||
menuconfig CRYPTO_SM4
|
||||
bool "using sm4"
|
||||
default n
|
||||
|
||||
menuconfig CRYPTO_SM9
|
||||
select CRYPTO_SM3
|
||||
select CRYPTO_SM4
|
||||
bool "using sm9"
|
||||
|
||||
default n
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_CRYPTO), y)
|
||||
SRC_DIR := crypto
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,15 @@
|
|||
SRC_FILES :=
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_SM3), y)
|
||||
SRC_FILES += sm3/sm3.c sm3/sm3_hmac.c test/sm3_test.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_SM4), y)
|
||||
SRC_FILES += sm4/sm4_common.c sm4/sms4_setkey.c sm4/sms4_enc.c sm4/sm4_enc_mode.c test/sm4_test.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_SM9), y)
|
||||
SRC_FILES += sm9/bignum.c sm9/ecc.c sm9/qn.c sm9/join.c sm9/sm9_util.c sm9/sm9_para.c sm9/sm9.c test/sm9_test.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 bn1 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 bignum.h
|
||||
* @brief arithmetic of big number, included by ecc.h
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef BIGNUM_H
|
||||
#define BIGNUM_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <xiuos.h>
|
||||
|
||||
#define BIGNUMBER_SIZE_8WORD 8
|
||||
#define BIGNUMBER_SIZE_16WORD 16
|
||||
|
||||
#define BIG8W_BYTESIZE 32
|
||||
|
||||
#define bool uint8_t
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef struct bignum_8uint32 {
|
||||
uint32_t word[BIGNUMBER_SIZE_8WORD];
|
||||
} big8w;
|
||||
|
||||
typedef struct bignum_16uint32 {
|
||||
uint32_t word[BIGNUMBER_SIZE_16WORD];
|
||||
uint8_t length;
|
||||
} big16w;
|
||||
|
||||
typedef struct SM9Curve {
|
||||
big8w b;
|
||||
big8w q;
|
||||
big8w N;
|
||||
} sm9curve;
|
||||
|
||||
extern sm9curve curve;
|
||||
|
||||
// used in Montgomery Mult
|
||||
/** power(2, 32) - (curve.q.word[0] 's reverse under power(2, 32)) */
|
||||
extern uint32_t qlow_reverse;
|
||||
/** power(2, 32) - (curve.N.word[0] 's reverse under power(2, 32)) */
|
||||
extern uint32_t Nlow_reverse;
|
||||
/** (2^(256*2)) mod curve.q; used in big numbers' mult(Montgomery Mult) */
|
||||
extern big8w q_2k;
|
||||
/** (2^(256*2)) mod curve.N; used in big numbers' mult(Montgomery Mult) */
|
||||
extern big8w N_2k;
|
||||
|
||||
void Big8wPrint(big8w* bignum);
|
||||
unsigned char Big8wHighestbit(big8w* bignum);
|
||||
bool Big8wIsZero(big8w* bignum);
|
||||
bool Big8wBigThan(big8w* bn1, big8w* bn2);
|
||||
bool Big8wEqual(big8w* bn1, big8w* bn2);
|
||||
big8w Big8wMinusMod(big8w bn1, big8w bn2, big8w p);
|
||||
big8w Big8wAddMod(big8w bn1, big8w bn2, big8w p);
|
||||
big8w Big16wmod8w(big16w bignum16w, big8w p);
|
||||
big8w Big8wReverse(big8w bignum, big8w N);
|
||||
big8w Big8wMultMod(big8w bn1, big8w bn2, big8w p);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.h
|
||||
* @brief arithmetic in ecc, included by qn.h
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef ECC_H
|
||||
#define ECC_H
|
||||
|
||||
#include <bignum.h>
|
||||
|
||||
typedef struct G1_base_group_point {
|
||||
big8w x;
|
||||
big8w y;
|
||||
} G1point;
|
||||
|
||||
typedef struct SM9ecn{
|
||||
big8w x;
|
||||
big8w y;
|
||||
big8w z;
|
||||
} ecn;
|
||||
|
||||
void G1pointPrint(G1point *point);
|
||||
bool PointInG1(G1point point);
|
||||
G1point G1pointAdd(G1point point1, G1point point2);
|
||||
G1point G1pointMult(big8w bignum, G1point point);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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 join.h
|
||||
* @brief convert data type and join string
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef JOIN_H
|
||||
#define JOIN_H
|
||||
|
||||
#include <qn.h>
|
||||
#include <sm3.h>
|
||||
|
||||
void Big8wIntou8string(big8w* bignum, uint8_t* string, uint32_t startindex);
|
||||
void Q12Intou8string(q12* num, uint8_t* string, uint32_t startindex);
|
||||
void U8stringToG1point(uint8_t *string, G1point* ret);
|
||||
|
||||
void JoinIDhid(uint8_t *ID, uint8_t IDlen, uint8_t hid, uint8_t *ret);
|
||||
void JoinMsgW(uint8_t *message, uint32_t msglen, q12 *w, uint8_t* ret);
|
||||
void JoinIDAIDBRARBg123(
|
||||
uint8_t *ID_Challenger, uint8_t ID_Challenger_len,
|
||||
uint8_t *ID_Responser, uint8_t ID_Responser_len,
|
||||
G1point* R_Challenger, G1point* R_Responser,
|
||||
q12 *g1, q12 *g2, q12 *g3,
|
||||
uint8_t* ret);
|
||||
void JoinCwID(G1point *C, q12 *w, uint8_t *ID, uint8_t IDlen, uint8_t *ret);
|
||||
|
||||
void XOR(unsigned char *msg, uint32_t msglen, unsigned char *K, unsigned char *ret);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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 qn.h
|
||||
* @brief arithmetic in extention field, and arithmetic in group G2, frobenius and LastPower in BiLinearPairing
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef QN_H
|
||||
#define QN_H
|
||||
|
||||
#include <ecc.h>
|
||||
|
||||
typedef struct q2_num {
|
||||
big8w high;
|
||||
big8w low;
|
||||
} q2;
|
||||
|
||||
typedef struct G2_q2group_point {
|
||||
q2 x;
|
||||
q2 y;
|
||||
} G2point;
|
||||
|
||||
typedef struct q4_num {
|
||||
q2 high;
|
||||
q2 low;
|
||||
} q4;
|
||||
|
||||
typedef struct q12_num {
|
||||
|
||||
q4 high;
|
||||
q4 mid;
|
||||
q4 low;
|
||||
|
||||
} q12;
|
||||
|
||||
typedef struct big_12bignum {
|
||||
big8w word[12];
|
||||
} big_12big;
|
||||
|
||||
extern big8w t; // sm9 ecc parameter
|
||||
extern big8w qnr; // (-1/2) mod curve.q
|
||||
extern big8w frobenius_constant_1[12];
|
||||
extern big8w frobenius_constant_2[12];
|
||||
|
||||
void G2pointPrint(G2point *point);
|
||||
void Q12Print(q12* number);
|
||||
void Q12To12big(q12 *num, big_12big *ret);
|
||||
G2point G2PointAdd(G2point point1, G2point point2);
|
||||
G2point G2PointMult(big8w num, G2point point);
|
||||
void Q12Zero(q12 *num);
|
||||
q12 Q12MultMod(q12 a, q12 b);
|
||||
q12 Q12PowerMod(q12 g, big8w r);
|
||||
void Q12Frobenius(q12 *f, uint8_t flag);
|
||||
void G2pointFrobenius(G2point Q, G2point* Q1, uint8_t flag);
|
||||
void Line(G1point P, G2point *T, G2point Q, bool doubleflag, q12 *f);
|
||||
void LastPower(q12 *f);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#ifndef SM3_H
|
||||
#define SM3_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SM3_DIGEST_LENGTH 32
|
||||
#define SM3_BLOCK_SIZE 64
|
||||
#define SM3_CBLOCK (SM3_BLOCK_SIZE)
|
||||
#define SM3_HMAC_SIZE (SM3_DIGEST_LENGTH)
|
||||
|
||||
# define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
# define GETU32(p) ((uint32_t)(p)[0]<<24|(uint32_t)(p)[1]<<16|(uint32_t)(p)[2]<<8|(uint32_t)(p)[3])
|
||||
# define PUTU32(p,v) ((p)[0]=(uint8_t)((v)>>24),(p)[1]=(uint8_t)((v)>>16),(p)[2]=(uint8_t)((v)>>8),(p)[3]=(uint8_t)(v))
|
||||
|
||||
#define FAR
|
||||
|
||||
typedef struct {
|
||||
uint32_t digest[8];
|
||||
uint64_t nblocks;
|
||||
unsigned char block[64];
|
||||
int num;
|
||||
} sm3_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
sm3_ctx_t sm3_ctx;
|
||||
unsigned char key[SM3_BLOCK_SIZE];
|
||||
} sm3_hmac_ctx_t;
|
||||
|
||||
void sm3_init(sm3_ctx_t *ctx);
|
||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len);
|
||||
void sm3_final(sm3_ctx_t *ctx, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
void sm3_compress(uint32_t digest[8], const unsigned char block[SM3_BLOCK_SIZE]);
|
||||
void sm3(const unsigned char *data, size_t datalen, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
int sm3_file(char *path, unsigned char output[32]);
|
||||
void sm3_compute_id_digest(unsigned char z[32], const char *id, const unsigned char x[32], const unsigned char y[32]);
|
||||
void sm3_hmac_init(sm3_hmac_ctx_t *ctx, const unsigned char *key, size_t key_len);
|
||||
void sm3_hmac_update(sm3_hmac_ctx_t *ctx, const unsigned char *data, size_t data_len);
|
||||
void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[SM3_HMAC_SIZE]);
|
||||
void sm3_hmac(const unsigned char *data, size_t data_len, const unsigned char *key, size_t key_len, unsigned char mac[SM3_HMAC_SIZE]);
|
||||
|
||||
void sm3_test_case();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: sm4.h
|
||||
Description: sm4 header file
|
||||
Others: take GMSSL master/include/openssl/sms4.h
|
||||
https://github.com/guanzhi/GmSSL/blob/master/include/openssl/sms4.h
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
*************************************************/
|
||||
|
||||
|
||||
#ifndef SM4_H
|
||||
#define SM4_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
# define SMS4_KEY_LENGTH 16
|
||||
# define SMS4_BLOCK_SIZE 16
|
||||
# define SMS4_IV_LENGTH (SMS4_BLOCK_SIZE)
|
||||
# define SMS4_NUM_ROUNDS 32
|
||||
|
||||
# define SM4_ERROR_UNKNOW -1
|
||||
# define SM4_MALLOC_FAIL -2
|
||||
# define SM4_BAD_KEY_LENGTH -3
|
||||
# define SM4_BAD_PADDING_FORMAT -4
|
||||
# define SM4_BAD_LENGTH -5
|
||||
|
||||
#define FAR
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t rk[SMS4_NUM_ROUNDS];
|
||||
} sms4_key_t;
|
||||
|
||||
typedef struct {
|
||||
sms4_key_t k1;
|
||||
sms4_key_t k2;
|
||||
sms4_key_t k3;
|
||||
} sms4_ede_key_t;
|
||||
|
||||
# define sms4_decrypt(in, out, key) sms4_encrypt(in,out,key)
|
||||
void sms4_set_encrypt_key(sms4_key_t *key, const unsigned char user_key[16]);
|
||||
void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char user_key[16]);
|
||||
void sms4_encrypt(const unsigned char in[16], unsigned char out[16], const sms4_key_t *key);
|
||||
void sms4_ecb_encrypt(const unsigned char *in, unsigned char *out, const sms4_key_t *key, int enc);
|
||||
|
||||
void Sms4EcbEncryptBlocks(const uint8_t *in,int ilen, uint8_t *out, const sms4_key_t *key);
|
||||
void Sms4EcbDecryptBlocks(const uint8_t *in,int ilen, uint8_t *out, const sms4_key_t *key);
|
||||
int Sms4EcbDecryptNoPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen , const sms4_key_t *key);
|
||||
int Sms4EcbEncryptNoPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen, const sms4_key_t *key);
|
||||
int Sms4EcbEncryptZeroPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen, const sms4_key_t *key);
|
||||
int Sms4EcbDecryptZeroPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen, const sms4_key_t *key);
|
||||
int Sms4EcbEncryptPkcs7Padding(const uint8_t *in,int ilen, uint8_t *out,int *olen, const sms4_key_t *key);
|
||||
int Sms4EcbDecryptPkcs7Padding(const uint8_t *in,int ilen, uint8_t *out,int *olen, const sms4_key_t *key);
|
||||
|
||||
void Sms4CbcEncryptBlocks(const unsigned char *in, int ilen, unsigned char *out,unsigned char *iv, const sms4_key_t *key);
|
||||
void Sms4CbcDecryptBlocks(const unsigned char *in, int ilen, unsigned char *out,unsigned char *iv, const sms4_key_t *key);
|
||||
int Sms4CbcDecryptNoPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen, uint8_t *iv,const sms4_key_t *key);
|
||||
int Sms4CbcEncryptNoPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv, const sms4_key_t *key);
|
||||
int Sms4CbcEncryptZeroPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv, const sms4_key_t *key);
|
||||
int Sms4CbcDecryptZeroPadding(const uint8_t *in,int ilen, uint8_t *out,int *olen, uint8_t *iv, const sms4_key_t *key);
|
||||
int Sms4CbcEncryptPkcs7Padding(const uint8_t *in,int ilen, uint8_t *out,int *olen, uint8_t *iv, const sms4_key_t *key);
|
||||
int Sms4CbcDecryptPkcs7Padding(const uint8_t *in,int ilen, uint8_t *out,int *olen, uint8_t *iv, const sms4_key_t *key);
|
||||
|
||||
// void sm4_test();
|
||||
void sm4_test_case();
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 sm9.h
|
||||
* @brief API of SM9
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef SM9_H
|
||||
#define SM9_H
|
||||
|
||||
#include <sm9_util.h>
|
||||
#include <sm9_para.h>
|
||||
|
||||
typedef struct SM9Signature {
|
||||
big8w h;
|
||||
G1point S;
|
||||
} Signature;
|
||||
|
||||
typedef struct SM9_Key_Package {
|
||||
unsigned char* K;
|
||||
G1point C;
|
||||
} Key_Package;
|
||||
|
||||
void SM9Init();
|
||||
Signature SM9Sign(unsigned char *message, uint32_t msglen, G1point ds, G2point Ppub_s);
|
||||
bool SM9VerifySignature(
|
||||
unsigned char *ID, unsigned char ID_len, unsigned char hid,
|
||||
unsigned char *message, uint32_t msglen,
|
||||
Signature signature, G2point Ppub_s);
|
||||
|
||||
void SM9KeyExchangeProduceR(unsigned char* ID, unsigned char IDlen, big8w* r, G1point* R, G1point encrypt_publickey);
|
||||
bool SM9KeyExchangeProduceKey(G1point* RA, G1point* RB, big8w* r, uint32_t klen_bitsize,
|
||||
unsigned char* challengerID, unsigned char challengerIDlen,
|
||||
unsigned char* responserID, unsigned char responserIDlen,
|
||||
q12 *g1, q12* g2, q12* g3, char* resultkey, bool sponsor,
|
||||
G1point encrypt_publickey, G2point encrypt_secretkey);
|
||||
bool SM9KeyExchangeVerifyKey(q12 *g1, q12 *g2, q12 *g3, G1point *RA, G1point *RB,
|
||||
unsigned char *challengerID, unsigned char challengerIDlen,
|
||||
unsigned char *responserID, unsigned char responserIDlen,
|
||||
unsigned char *S1, unsigned char *SA);
|
||||
|
||||
void SM9KeyPackage(unsigned char* ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e, uint32_t klen_bitsize, unsigned char* K, G1point* C);
|
||||
bool SM9KeyDepackage(G1point C, G2point de, unsigned char* ID, unsigned char IDlen, unsigned int klen_bitsize, unsigned char* K);
|
||||
|
||||
bool SM9EncryptWithKDF(unsigned char *message, unsigned int msglen_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e, unsigned char *C);
|
||||
bool SM9DecryptWithKDF(unsigned char *ID, unsigned char IDlen,
|
||||
unsigned char *message, unsigned int msglen_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *C, G2point encrypt_secretkey);
|
||||
|
||||
bool SM9EncryptWithSM4(unsigned char *message, unsigned int msglen_bytesize,
|
||||
unsigned int K1_len_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e,
|
||||
unsigned char *C);
|
||||
bool SM9DecryptWithSM4(unsigned char *ID, unsigned char IDlen,
|
||||
unsigned char *message, unsigned int msglen, unsigned int K1_len_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *C, unsigned int Cbyteslen, G2point encrypt_secretkey);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 sm9_para.h
|
||||
* @brief initialize paramters of SM9
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef SM9_PARA_H
|
||||
#define SM9_PARA_H
|
||||
|
||||
#include <join.h>
|
||||
|
||||
//extern char *device_id;
|
||||
//extern char *platform_id;
|
||||
|
||||
extern G1point P1;
|
||||
extern G2point P2;
|
||||
//extern G2point sign_publickey, encrypt_secretkey;
|
||||
//extern G1point sign_secretkey, encrypt_publickey;
|
||||
|
||||
extern const uint32_t sm9_q[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_N[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P1_x[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P1_y[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P2_x_high[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P2_x_low[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P2_y_high[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_P2_y_low[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_1[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_2[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_3[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_4[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_5[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_6[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_7[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_8[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_9[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_10[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc1_11[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_2[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_3[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_4[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_5[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_6[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_7[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_8[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_9[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_10[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t fc2_11[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_qnr[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_q_2k[BIGNUMBER_SIZE_8WORD];
|
||||
extern const uint32_t sm9_N_2k[BIGNUMBER_SIZE_8WORD];
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 sm9_test.h
|
||||
* @brief tests of SM9
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef SM9_TEST_H
|
||||
#define SM9_TEST_H
|
||||
|
||||
#include <sm9.h>
|
||||
|
||||
void SignAndVerifyTest();
|
||||
void SM9KeyExchangeTest();
|
||||
void SM9PackDepackTest();
|
||||
void SM9EncryptDecryptTest();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 sm9_util.h
|
||||
* @brief the function called by SM9 function, including hash, KDF, produce random number, encrypt and decrypt algorithm, BiLinearPairing
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef SM9_UTIL_H
|
||||
#define SM9_UTIL_H
|
||||
|
||||
#include <join.h>
|
||||
#include <sm4.h>
|
||||
|
||||
#define SM3OUT_32BYTES 32 // (256 / 8)
|
||||
|
||||
void HashTwice(uint8_t *ID_A, uint8_t ID_A_len, uint8_t *ID_B, uint8_t ID_B_len,
|
||||
G1point *RA, G1point *RB,
|
||||
q12 *g1, q12 *g2, q12 *g3, uint8_t funcflag, uint8_t *ret);
|
||||
big8w RandomNumGenerate();
|
||||
bool StringEqualZero(uint8_t* string, uint32_t stringlen);
|
||||
big8w H(uint8_t *Z, uint32_t Zlen, uint8_t funcflag);
|
||||
void KDF(uint8_t *Z, uint32_t Zlen, uint32_t klen, uint8_t *ret);
|
||||
void SM4EncryptWithEcbMode(uint8_t* message, uint32_t msglen, uint8_t* key, uint8_t* ciphertext);
|
||||
void SM4DecryptWithEcbMode(uint8_t* ciphertext, uint32_t ciphertextlen, uint8_t* message, int msglen, uint8_t* key);
|
||||
q12 BiLinearPairing(G1point P, G2point Q);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,474 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <sm3.h>
|
||||
|
||||
static void sm3_compress_blocks(uint32_t digest[8],
|
||||
const unsigned char *data, size_t blocks);
|
||||
|
||||
void sm3_init(sm3_ctx_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->digest[0] = 0x7380166F;
|
||||
ctx->digest[1] = 0x4914B2B9;
|
||||
ctx->digest[2] = 0x172442D7;
|
||||
ctx->digest[3] = 0xDA8A0600;
|
||||
ctx->digest[4] = 0xA96F30BC;
|
||||
ctx->digest[5] = 0x163138AA;
|
||||
ctx->digest[6] = 0xE38DEE4D;
|
||||
ctx->digest[7] = 0xB0FB0E4E;
|
||||
}
|
||||
|
||||
void sm3_compute_id_digest(unsigned char z[32], const char *id,
|
||||
const unsigned char x[32], const unsigned char y[32])
|
||||
{
|
||||
unsigned char zin[] = {
|
||||
0x00, 0x80,
|
||||
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
|
||||
0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34,
|
||||
0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7,
|
||||
0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92,
|
||||
0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93,
|
||||
0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19,
|
||||
0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94,
|
||||
0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1,
|
||||
0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7,
|
||||
0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C,
|
||||
0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53,
|
||||
0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40,
|
||||
0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x90,
|
||||
};
|
||||
|
||||
if (!id || strcmp(id, "1234567812345678")) {
|
||||
unsigned int digest[8] = {
|
||||
0xadadedb5U, 0x0446043fU, 0x08a87aceU, 0xe86d2243U,
|
||||
0x8e232383U, 0xbfc81fe2U, 0xcf9117c8U, 0x4707011dU,
|
||||
};
|
||||
memcpy(&zin[128], x, 32);
|
||||
memcpy(&zin[160], y, 32);
|
||||
sm3_compress_blocks(digest, zin, 2);
|
||||
PUTU32(z , digest[0]);
|
||||
PUTU32(z + 4, digest[1]);
|
||||
PUTU32(z + 8, digest[2]);
|
||||
PUTU32(z + 12, digest[3]);
|
||||
PUTU32(z + 16, digest[4]);
|
||||
PUTU32(z + 20, digest[5]);
|
||||
PUTU32(z + 24, digest[6]);
|
||||
PUTU32(z + 28, digest[7]);
|
||||
|
||||
} else {
|
||||
sm3_ctx_t ctx;
|
||||
unsigned char idbits[2];
|
||||
size_t len;
|
||||
|
||||
len = strlen(id);
|
||||
idbits[0] = (unsigned char)(len >> 5);
|
||||
idbits[1] = (unsigned char)(len << 3);
|
||||
|
||||
sm3_init(&ctx);
|
||||
sm3_update(&ctx, idbits, 2);
|
||||
sm3_update(&ctx, (unsigned char *)id, len);
|
||||
sm3_update(&ctx, zin + 18, 128);
|
||||
sm3_update(&ctx, x, 32);
|
||||
sm3_update(&ctx, y, 32);
|
||||
sm3_final(&ctx, z);
|
||||
}
|
||||
}
|
||||
|
||||
int sm3_sm2_init(sm3_ctx_t *ctx, const char *id,
|
||||
const unsigned char *x, const unsigned char *y)
|
||||
{
|
||||
unsigned char z[32];
|
||||
if ((id && strlen(id) > 65535/8) || !x || !y) {
|
||||
return 0;
|
||||
}
|
||||
sm3_compute_id_digest(z, id, x, y);
|
||||
sm3_init(ctx);
|
||||
sm3_update(ctx, z, 32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char *data, size_t data_len)
|
||||
{
|
||||
size_t blocks;
|
||||
|
||||
if (ctx->num) {
|
||||
unsigned int left = SM3_BLOCK_SIZE - ctx->num;
|
||||
if (data_len < left) {
|
||||
memcpy(ctx->block + ctx->num, data, data_len);
|
||||
ctx->num += data_len;
|
||||
return;
|
||||
} else {
|
||||
memcpy(ctx->block + ctx->num, data, left);
|
||||
sm3_compress_blocks(ctx->digest, ctx->block, 1);
|
||||
ctx->nblocks++;
|
||||
data += left;
|
||||
data_len -= left;
|
||||
}
|
||||
}
|
||||
|
||||
blocks = data_len / SM3_BLOCK_SIZE;
|
||||
sm3_compress_blocks(ctx->digest, data, blocks);
|
||||
ctx->nblocks += blocks;
|
||||
data += SM3_BLOCK_SIZE * blocks;
|
||||
data_len -= SM3_BLOCK_SIZE * blocks;
|
||||
|
||||
ctx->num = data_len;
|
||||
if (data_len) {
|
||||
memcpy(ctx->block, data, data_len);
|
||||
}
|
||||
}
|
||||
|
||||
void sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
|
||||
{
|
||||
int i;
|
||||
|
||||
ctx->block[ctx->num] = 0x80;
|
||||
|
||||
if (ctx->num + 9 <= SM3_BLOCK_SIZE) {
|
||||
memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9);
|
||||
} else {
|
||||
memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1);
|
||||
sm3_compress(ctx->digest, ctx->block);
|
||||
memset(ctx->block, 0, SM3_BLOCK_SIZE - 8);
|
||||
}
|
||||
PUTU32(ctx->block + 56, ctx->nblocks >> 23);
|
||||
PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3));
|
||||
|
||||
sm3_compress(ctx->digest, ctx->block);
|
||||
for (i = 0; i < 8; i++) {
|
||||
PUTU32(digest + i*4, ctx->digest[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#define ROTL(x,n) (((x)<<(n)) | ((x)>>(32-(n))))
|
||||
#define P0(x) ((x) ^ ROL32((x), 9) ^ ROL32((x),17))
|
||||
#define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23))
|
||||
|
||||
#define FF00(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z)))
|
||||
#define GG00(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define GG16(x,y,z) ((((y)^(z)) & (x)) ^ (z))
|
||||
|
||||
#define R(A, B, C, D, E, F, G, H, xx) \
|
||||
SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); \
|
||||
SS2 = SS1 ^ ROL32(A, 12); \
|
||||
TT1 = FF##xx(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); \
|
||||
TT2 = GG##xx(E, F, G) + H + SS1 + W[j]; \
|
||||
B = ROL32(B, 9); \
|
||||
H = TT1; \
|
||||
F = ROL32(F, 19); \
|
||||
D = P0(TT2); \
|
||||
j++
|
||||
|
||||
#define R8(A, B, C, D, E, F, G, H, xx) \
|
||||
R(A, B, C, D, E, F, G, H, xx); \
|
||||
R(H, A, B, C, D, E, F, G, xx); \
|
||||
R(G, H, A, B, C, D, E, F, xx); \
|
||||
R(F, G, H, A, B, C, D, E, xx); \
|
||||
R(E, F, G, H, A, B, C, D, xx); \
|
||||
R(D, E, F, G, H, A, B, C, xx); \
|
||||
R(C, D, E, F, G, H, A, B, xx); \
|
||||
R(B, C, D, E, F, G, H, A, xx)
|
||||
|
||||
|
||||
|
||||
#define T00 0x79cc4519U
|
||||
#define T16 0x7a879d8aU
|
||||
|
||||
#define K0 0x79cc4519U
|
||||
#define K1 0xf3988a32U
|
||||
#define K2 0xe7311465U
|
||||
#define K3 0xce6228cbU
|
||||
#define K4 0x9cc45197U
|
||||
#define K5 0x3988a32fU
|
||||
#define K6 0x7311465eU
|
||||
#define K7 0xe6228cbcU
|
||||
#define K8 0xcc451979U
|
||||
#define K9 0x988a32f3U
|
||||
#define K10 0x311465e7U
|
||||
#define K11 0x6228cbceU
|
||||
#define K12 0xc451979cU
|
||||
#define K13 0x88a32f39U
|
||||
#define K14 0x11465e73U
|
||||
#define K15 0x228cbce6U
|
||||
#define K16 0x9d8a7a87U
|
||||
#define K17 0x3b14f50fU
|
||||
#define K18 0x7629ea1eU
|
||||
#define K19 0xec53d43cU
|
||||
#define K20 0xd8a7a879U
|
||||
#define K21 0xb14f50f3U
|
||||
#define K22 0x629ea1e7U
|
||||
#define K23 0xc53d43ceU
|
||||
#define K24 0x8a7a879dU
|
||||
#define K25 0x14f50f3bU
|
||||
#define K26 0x29ea1e76U
|
||||
#define K27 0x53d43cecU
|
||||
#define K28 0xa7a879d8U
|
||||
#define K29 0x4f50f3b1U
|
||||
#define K30 0x9ea1e762U
|
||||
#define K31 0x3d43cec5U
|
||||
#define K32 0x7a879d8aU
|
||||
#define K33 0xf50f3b14U
|
||||
#define K34 0xea1e7629U
|
||||
#define K35 0xd43cec53U
|
||||
#define K36 0xa879d8a7U
|
||||
#define K37 0x50f3b14fU
|
||||
#define K38 0xa1e7629eU
|
||||
#define K39 0x43cec53dU
|
||||
#define K40 0x879d8a7aU
|
||||
#define K41 0x0f3b14f5U
|
||||
#define K42 0x1e7629eaU
|
||||
#define K43 0x3cec53d4U
|
||||
#define K44 0x79d8a7a8U
|
||||
#define K45 0xf3b14f50U
|
||||
#define K46 0xe7629ea1U
|
||||
#define K47 0xcec53d43U
|
||||
#define K48 0x9d8a7a87U
|
||||
#define K49 0x3b14f50fU
|
||||
#define K50 0x7629ea1eU
|
||||
#define K51 0xec53d43cU
|
||||
#define K52 0xd8a7a879U
|
||||
#define K53 0xb14f50f3U
|
||||
#define K54 0x629ea1e7U
|
||||
#define K55 0xc53d43ceU
|
||||
#define K56 0x8a7a879dU
|
||||
#define K57 0x14f50f3bU
|
||||
#define K58 0x29ea1e76U
|
||||
#define K59 0x53d43cecU
|
||||
#define K60 0xa7a879d8U
|
||||
#define K61 0x4f50f3b1U
|
||||
#define K62 0x9ea1e762U
|
||||
#define K63 0x3d43cec5U
|
||||
|
||||
uint32_t K[64] = {
|
||||
K0, K1, K2, K3, K4, K5, K6, K7,
|
||||
K8, K9, K10, K11, K12, K13, K14, K15,
|
||||
K16, K17, K18, K19, K20, K21, K22, K23,
|
||||
K24, K25, K26, K27, K28, K29, K30, K31,
|
||||
K32, K33, K34, K35, K36, K37, K38, K39,
|
||||
K40, K41, K42, K43, K44, K45, K46, K47,
|
||||
K48, K49, K50, K51, K52, K53, K54, K55,
|
||||
K56, K57, K58, K59, K60, K61, K62, K63,
|
||||
/*
|
||||
0x79cc4519U, 0xf3988a32U, 0xe7311465U, 0xce6228cbU,
|
||||
0x9cc45197U, 0x3988a32fU, 0x7311465eU, 0xe6228cbcU,
|
||||
0xcc451979U, 0x988a32f3U, 0x311465e7U, 0x6228cbceU,
|
||||
0xc451979cU, 0x88a32f39U, 0x11465e73U, 0x228cbce6U,
|
||||
0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU,
|
||||
0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU,
|
||||
0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU,
|
||||
0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U,
|
||||
0x7a879d8aU, 0xf50f3b14U, 0xea1e7629U, 0xd43cec53U,
|
||||
0xa879d8a7U, 0x50f3b14fU, 0xa1e7629eU, 0x43cec53dU,
|
||||
0x879d8a7aU, 0x0f3b14f5U, 0x1e7629eaU, 0x3cec53d4U,
|
||||
0x79d8a7a8U, 0xf3b14f50U, 0xe7629ea1U, 0xcec53d43U,
|
||||
0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU,
|
||||
0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU,
|
||||
0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU,
|
||||
0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U,
|
||||
*/
|
||||
};
|
||||
|
||||
static void sm3_compress_blocks(uint32_t digest[8],
|
||||
const unsigned char *data, size_t blocks)
|
||||
{
|
||||
uint32_t A;
|
||||
uint32_t B;
|
||||
uint32_t C;
|
||||
uint32_t D;
|
||||
uint32_t E;
|
||||
uint32_t F;
|
||||
uint32_t G;
|
||||
uint32_t H;
|
||||
uint32_t W[68];
|
||||
uint32_t SS1, SS2, TT1, TT2;
|
||||
int j;
|
||||
|
||||
while (blocks--) {
|
||||
|
||||
A = digest[0];
|
||||
B = digest[1];
|
||||
C = digest[2];
|
||||
D = digest[3];
|
||||
E = digest[4];
|
||||
F = digest[5];
|
||||
G = digest[6];
|
||||
H = digest[7];
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
W[j] = GETU32(data + j*4);
|
||||
|
||||
for (; j < 68; j++)
|
||||
W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15))
|
||||
^ ROL32(W[j - 13], 7) ^ W[j - 6];
|
||||
|
||||
|
||||
|
||||
j = 0;
|
||||
|
||||
#define FULL_UNROLL
|
||||
#ifdef FULL_UNROLL
|
||||
R8(A, B, C, D, E, F, G, H, 00);
|
||||
R8(A, B, C, D, E, F, G, H, 00);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
R8(A, B, C, D, E, F, G, H, 16);
|
||||
#else
|
||||
for (; j < 16; j++) {
|
||||
SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7);
|
||||
SS2 = SS1 ^ ROL32(A, 12);
|
||||
TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]);
|
||||
TT2 = GG00(E, F, G) + H + SS1 + W[j];
|
||||
D = C;
|
||||
C = ROL32(B, 9);
|
||||
B = A;
|
||||
A = TT1;
|
||||
H = G;
|
||||
G = ROL32(F, 19);
|
||||
F = E;
|
||||
E = P0(TT2);
|
||||
}
|
||||
|
||||
for (; j < 64; j++) {
|
||||
SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7);
|
||||
SS2 = SS1 ^ ROL32(A, 12);
|
||||
TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]);
|
||||
TT2 = GG16(E, F, G) + H + SS1 + W[j];
|
||||
D = C;
|
||||
C = ROL32(B, 9);
|
||||
B = A;
|
||||
A = TT1;
|
||||
H = G;
|
||||
G = ROL32(F, 19);
|
||||
F = E;
|
||||
E = P0(TT2);
|
||||
}
|
||||
#endif
|
||||
|
||||
digest[0] ^= A;
|
||||
digest[1] ^= B;
|
||||
digest[2] ^= C;
|
||||
digest[3] ^= D;
|
||||
digest[4] ^= E;
|
||||
digest[5] ^= F;
|
||||
digest[6] ^= G;
|
||||
digest[7] ^= H;
|
||||
|
||||
data += 64;
|
||||
}
|
||||
}
|
||||
|
||||
void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||
{
|
||||
return sm3_compress_blocks(digest, block, 1);
|
||||
}
|
||||
|
||||
void sm3(const unsigned char *msg, size_t msglen,
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH])
|
||||
{
|
||||
sm3_ctx_t ctx;
|
||||
|
||||
sm3_init(&ctx);
|
||||
sm3_update(&ctx, msg, msglen);
|
||||
sm3_final(&ctx, dgst);
|
||||
|
||||
memset(&ctx, 0, sizeof(sm3_ctx_t));
|
||||
}
|
||||
|
||||
int sm3_file(char *path, unsigned char output[32])
|
||||
{
|
||||
FILE *f;
|
||||
size_t n;
|
||||
sm3_ctx_t ctx;
|
||||
unsigned char buf[1024];
|
||||
|
||||
if ((f = fopen(path, "rb")) == NULL)
|
||||
return(1);
|
||||
|
||||
sm3_init(&ctx);
|
||||
|
||||
while ((n = fread(buf, 1, sizeof(buf), f)) > 0)
|
||||
sm3_update(&ctx, buf, (int)n);
|
||||
|
||||
sm3_final(&ctx, output);
|
||||
|
||||
memset(&ctx, 0, sizeof(sm3_ctx_t));
|
||||
|
||||
if (ferror(f) != 0)
|
||||
{
|
||||
fclose(f);
|
||||
return(2);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sm3.h>
|
||||
|
||||
/**
|
||||
* HMAC_k(m) = H((k ^ opad), H((k ^ ipad), m))
|
||||
* pseudo-code:
|
||||
* function hmac(key, message)
|
||||
* opad = [0x5c * blocksize]
|
||||
* ipad = [0x36 * blocksize]
|
||||
* if (length(key) > blocksize) then
|
||||
* key = hash(key)
|
||||
* end if
|
||||
* for i from 0 to length(key) - 1 step 1
|
||||
* ipad[i] = ipad[i] XOR key[i]
|
||||
* opad[i] = opad[i] XOR key[i]
|
||||
* end for
|
||||
* return hash(opad || hash(ipad || message))
|
||||
* end function
|
||||
*/
|
||||
|
||||
|
||||
#define IPAD 0x36
|
||||
#define OPAD 0x5C
|
||||
|
||||
void sm3_hmac_init(sm3_hmac_ctx_t *ctx, const unsigned char *key, size_t key_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (key_len <= SM3_BLOCK_SIZE) {
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->key + key_len, 0, SM3_BLOCK_SIZE - key_len);
|
||||
} else {
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, key, key_len);
|
||||
sm3_final(&ctx->sm3_ctx, ctx->key);
|
||||
memset(ctx->key + SM3_DIGEST_LENGTH, 0,
|
||||
SM3_BLOCK_SIZE - SM3_DIGEST_LENGTH);
|
||||
}
|
||||
for (i = 0; i < SM3_BLOCK_SIZE; i++) {
|
||||
ctx->key[i] ^= IPAD;
|
||||
}
|
||||
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void sm3_hmac_update(sm3_hmac_ctx_t *ctx,
|
||||
const unsigned char *data, size_t data_len)
|
||||
{
|
||||
sm3_update(&ctx->sm3_ctx, data, data_len);
|
||||
}
|
||||
|
||||
void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[SM3_HMAC_SIZE])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SM3_BLOCK_SIZE; i++) {
|
||||
ctx->key[i] ^= (IPAD ^ OPAD);
|
||||
}
|
||||
sm3_final(&ctx->sm3_ctx, mac);
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
|
||||
sm3_update(&ctx->sm3_ctx, mac, SM3_DIGEST_LENGTH);
|
||||
sm3_final(&ctx->sm3_ctx, mac);
|
||||
}
|
||||
|
||||
void sm3_hmac(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len,
|
||||
unsigned char mac[SM3_HMAC_SIZE])
|
||||
{
|
||||
sm3_hmac_ctx_t ctx;
|
||||
sm3_hmac_init(&ctx, key, key_len);
|
||||
sm3_hmac_update(&ctx, data, data_len);
|
||||
sm3_hmac_final(&ctx, mac);
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,265 @@
|
|||
/**
|
||||
* 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 bn1 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 sm4_enc_mode.c
|
||||
* @brief sm4 encry and decrypt functions
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <sm4.h>
|
||||
|
||||
int ZeroPadding(const uint8_t *input, int ilen, uint8_t *output, int *olen) {
|
||||
int padding_len = 0;
|
||||
if (ilen % 16 == 0) {
|
||||
padding_len = ilen + 16;
|
||||
}
|
||||
else {
|
||||
padding_len = ilen + (16 - ilen % 16);
|
||||
}
|
||||
memset(output, 0x00, sizeof(char) * padding_len);
|
||||
memcpy(output, input, ilen);
|
||||
*olen = padding_len;
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int ZeroUnPadding(uint8_t *input, int *ilen) {
|
||||
if ( *ilen % 16 != 0) {
|
||||
return SM4_BAD_PADDING_FORMAT;
|
||||
}
|
||||
while (*(input + *ilen - 1) == 0x00) {
|
||||
(*ilen)--;
|
||||
}
|
||||
return *ilen;
|
||||
}
|
||||
|
||||
int Pkcs7Padding(const uint8_t *input, int ilen, uint8_t *output , int *olen) {
|
||||
int len_after_Padding;
|
||||
uint8_t padding_value;
|
||||
if (ilen == 0)
|
||||
{
|
||||
return SM4_BAD_LENGTH;
|
||||
}
|
||||
padding_value = 16 - ilen % 16;
|
||||
len_after_Padding = ilen + padding_value;
|
||||
|
||||
memset(output, 0x00, sizeof(char) * len_after_Padding);
|
||||
memcpy(output, input, ilen);
|
||||
for (int i = ilen; i < len_after_Padding; i++) {
|
||||
*(output + i) = padding_value;
|
||||
}
|
||||
*olen = len_after_Padding;
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Pkcs7UnPadding(uint8_t *input, int *ilen) {
|
||||
if (*ilen % 16 != 0) {
|
||||
return SM4_BAD_PADDING_FORMAT;
|
||||
}
|
||||
uint8_t value = *(input + *ilen - 1);
|
||||
*ilen = *ilen - value;
|
||||
*(input + *ilen) = 0x00;
|
||||
return *ilen;
|
||||
}
|
||||
|
||||
|
||||
void Sms4EcbEncryptBlocks(const uint8_t *in, int ilen, uint8_t *out,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int blocks;
|
||||
blocks = ilen / 16;
|
||||
|
||||
while (blocks--) {
|
||||
sms4_encrypt(in, out, key);
|
||||
in += 16;
|
||||
out += 16;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Sms4EcbDecryptBlocks(const uint8_t *in, int ilen, uint8_t *out, const sms4_key_t *key)
|
||||
{
|
||||
int blocks;
|
||||
blocks = ilen / 16;
|
||||
|
||||
while (blocks--) {
|
||||
sms4_decrypt(in, out, key);
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
int Sms4EcbDecryptNoPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen , const sms4_key_t *key)
|
||||
{
|
||||
if ( ilen % 16 != 0){
|
||||
return SM4_BAD_LENGTH;
|
||||
}
|
||||
Sms4EcbDecryptBlocks(in ,ilen, out , key );
|
||||
*olen = ilen;
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4EcbEncryptNoPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
if ( ilen % 16 != 0){
|
||||
return SM4_BAD_LENGTH;
|
||||
}
|
||||
memset(out, 0x00, sizeof(char) * ilen);
|
||||
Sms4EcbEncryptBlocks(in ,ilen, out , key );
|
||||
*olen = ilen;
|
||||
return *olen;
|
||||
}
|
||||
|
||||
|
||||
int Sms4EcbEncryptZeroPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
uint8_t *padding_value;
|
||||
int plen;
|
||||
int res ;
|
||||
res = ZeroPadding(in, ilen, out, olen);
|
||||
if (res < 0){
|
||||
return res;
|
||||
}
|
||||
Sms4EcbEncryptBlocks(out, *olen, out, key);
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4EcbDecryptZeroPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int res = 0;
|
||||
Sms4EcbDecryptBlocks(in, ilen, out, key);
|
||||
res = ZeroUnPadding(out, olen);
|
||||
return res;
|
||||
}
|
||||
|
||||
int Sms4EcbEncryptPkcs7Padding(const uint8_t *in, int ilen, uint8_t *out, int *olen,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int res;
|
||||
res = Pkcs7Padding(in, ilen, out, olen);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
Sms4EcbEncryptBlocks(out, *olen, out, key);
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4EcbDecryptPkcs7Padding(const uint8_t *in, int ilen, uint8_t *out, int *olen,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int res;
|
||||
Sms4EcbDecryptBlocks(in, ilen, out, key);
|
||||
res = Pkcs7UnPadding(out, olen);
|
||||
return res;
|
||||
}
|
||||
|
||||
void Sms4CbcEncryptBlocks(const unsigned char *in, int ilen, unsigned char *out,unsigned char *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int blocks, i;
|
||||
blocks = ilen / 16;
|
||||
while (blocks--) {
|
||||
for( i = 0; i < 16; i++ )
|
||||
out[i] = (unsigned char)( in[i] ^ iv[i] );
|
||||
sms4_encrypt(out, out, key);
|
||||
memcpy( iv, out, 16 );
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void Sms4CbcDecryptBlocks(const unsigned char *in, int ilen, unsigned char *out,unsigned char *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int blocks, i;
|
||||
blocks = ilen / 16;
|
||||
unsigned char temp[16];
|
||||
while (blocks--) {
|
||||
memcpy( temp, in, 16 );
|
||||
sms4_decrypt(in, out, key);
|
||||
for( i = 0; i < 16; i++ )
|
||||
out[i] = (unsigned char)( out[i] ^ iv[i] );
|
||||
memcpy( iv, temp, 16 );
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
int Sms4CbcDecryptNoPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv,const sms4_key_t *key)
|
||||
{
|
||||
if ( ilen % 16 != 0){
|
||||
return SM4_BAD_LENGTH;
|
||||
}
|
||||
*olen = ilen;
|
||||
Sms4CbcDecryptBlocks(in , ilen, out ,iv, key );
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4CbcEncryptNoPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen,uint8_t *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
if ( ilen % 16 != 0){
|
||||
return SM4_BAD_LENGTH;
|
||||
}
|
||||
*olen = ilen;
|
||||
Sms4CbcEncryptBlocks(in , ilen, out , iv, key );
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4CbcEncryptZeroPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int res ;
|
||||
res = ZeroPadding(in, ilen, out, olen);
|
||||
if (res < 0)
|
||||
return res;
|
||||
Sms4CbcEncryptBlocks(out, *olen, out,iv, key);
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4CbcDecryptZeroPadding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
|
||||
*olen = ilen;
|
||||
int res ;
|
||||
Sms4CbcDecryptBlocks(in, ilen, out,iv, key);
|
||||
res = ZeroUnPadding(out, olen);
|
||||
return res;
|
||||
}
|
||||
|
||||
int Sms4CbcEncryptPkcs7Padding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
int res;
|
||||
res = Pkcs7Padding(in, ilen, out, olen);
|
||||
if (res < 0)
|
||||
return res;
|
||||
Sms4CbcEncryptBlocks(out, *olen, out,iv, key);
|
||||
return *olen;
|
||||
}
|
||||
|
||||
int Sms4CbcDecryptPkcs7Padding(const uint8_t *in, int ilen, uint8_t *out, int *olen, uint8_t *iv,
|
||||
const sms4_key_t *key)
|
||||
{
|
||||
*olen = ilen;
|
||||
int res;
|
||||
Sms4CbcDecryptBlocks(in, ilen, out,iv, key);
|
||||
res = Pkcs7UnPadding(out, olen);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2019 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <sm4.h>
|
||||
#include "sms4_lcl.h"
|
||||
|
||||
#define L32(x) \
|
||||
((x) ^ \
|
||||
ROL32((x), 2) ^ \
|
||||
ROL32((x), 10) ^ \
|
||||
ROL32((x), 18) ^ \
|
||||
ROL32((x), 24))
|
||||
|
||||
#define ROUND_SBOX(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
|
||||
x4 = S32(x4); \
|
||||
x4 = x0 ^ L32(x4)
|
||||
|
||||
#define ROUND_TBOX(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
|
||||
t0 = ROL32(SMS4_T[(uint8_t)x4], 8); \
|
||||
x4 >>= 8; \
|
||||
x0 ^= t0; \
|
||||
t0 = ROL32(SMS4_T[(uint8_t)x4], 16); \
|
||||
x4 >>= 8; \
|
||||
x0 ^= t0; \
|
||||
t0 = ROL32(SMS4_T[(uint8_t)x4], 24); \
|
||||
x4 >>= 8; \
|
||||
x0 ^= t0; \
|
||||
t1 = SMS4_T[x4]; \
|
||||
x4 = x0 ^ t1
|
||||
|
||||
#define ROUND_DBOX(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
|
||||
x4 = x0 ^ SMS4_D[(uint16_t)(x4 >> 16)] ^ \
|
||||
ROL32(SMS4_D[(uint16_t)x4], 16)
|
||||
|
||||
#define ROUND ROUND_TBOX
|
||||
|
||||
void sms4_encrypt(const unsigned char in[16], unsigned char out[16], const sms4_key_t *key)
|
||||
{
|
||||
const uint *rk = key->rk;
|
||||
uint x0, x1, x2, x3, x4;
|
||||
uint t0, t1;
|
||||
|
||||
x0 = GETU32(in);
|
||||
x1 = GETU32(in + 4);
|
||||
x2 = GETU32(in + 8);
|
||||
x3 = GETU32(in + 12);
|
||||
#define ROUND ROUND_TBOX
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
|
||||
PUTU32(out, x0);
|
||||
PUTU32(out + 4, x4);
|
||||
PUTU32(out + 8, x3);
|
||||
PUTU32(out + 12, x2);
|
||||
}
|
||||
|
||||
/* caller make sure counter not overflow */
|
||||
void sms4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
int blocks, const sms4_key_t *key, const unsigned char iv[16])
|
||||
{
|
||||
const uint *rk = key->rk;
|
||||
unsigned int c0 = GETU32(iv);
|
||||
unsigned int c1 = GETU32(iv + 4);
|
||||
unsigned int c2 = GETU32(iv + 8);
|
||||
unsigned int c3 = GETU32(iv + 12);
|
||||
uint x0, x1, x2, x3, x4;
|
||||
uint t0, t1;
|
||||
|
||||
while (blocks--) {
|
||||
x0 = c0;
|
||||
x1 = c1;
|
||||
x2 = c2;
|
||||
x3 = c3;
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
PUTU32(out, GETU32(in) ^ x0);
|
||||
PUTU32(out + 4, GETU32(in + 4) ^ x4);
|
||||
PUTU32(out + 8, GETU32(in + 8) ^ x3);
|
||||
PUTU32(out + 12, GETU32(in + 12) ^ x2);
|
||||
in += 16;
|
||||
out += 16;
|
||||
c3++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2019 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#ifndef HEADER_SMS4_LCL_H
|
||||
#define HEADER_SMS4_LCL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
# define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
# define GETU32(p) ((uint)(p)[0]<<24|(uint)(p)[1]<<16|(uint)(p)[2]<<8|(uint)(p)[3])
|
||||
# define PUTU32(p,v) ((p)[0]=(uint8_t)((v)>>24),(p)[1]=(uint8_t)((v)>>16),(p)[2]=(uint8_t)((v)>>8),(p)[3]=(uint8_t)(v))
|
||||
|
||||
extern const uint8_t SMS4_S[256];
|
||||
extern const uint32_t SMS4_T[256];
|
||||
extern const uint32_t SMS4_D[65536];
|
||||
|
||||
#define S32(A) \
|
||||
((SMS4_S[((A) >> 24) ] << 24) ^ \
|
||||
(SMS4_S[((A) >> 16) & 0xff] << 16) ^ \
|
||||
(SMS4_S[((A) >> 8) & 0xff] << 8) ^ \
|
||||
(SMS4_S[((A)) & 0xff]))
|
||||
|
||||
#define ROUNDS(x0, x1, x2, x3, x4) \
|
||||
ROUND(x0, x1, x2, x3, x4, 0); \
|
||||
ROUND(x1, x2, x3, x4, x0, 1); \
|
||||
ROUND(x2, x3, x4, x0, x1, 2); \
|
||||
ROUND(x3, x4, x0, x1, x2, 3); \
|
||||
ROUND(x4, x0, x1, x2, x3, 4); \
|
||||
ROUND(x0, x1, x2, x3, x4, 5); \
|
||||
ROUND(x1, x2, x3, x4, x0, 6); \
|
||||
ROUND(x2, x3, x4, x0, x1, 7); \
|
||||
ROUND(x3, x4, x0, x1, x2, 8); \
|
||||
ROUND(x4, x0, x1, x2, x3, 9); \
|
||||
ROUND(x0, x1, x2, x3, x4, 10); \
|
||||
ROUND(x1, x2, x3, x4, x0, 11); \
|
||||
ROUND(x2, x3, x4, x0, x1, 12); \
|
||||
ROUND(x3, x4, x0, x1, x2, 13); \
|
||||
ROUND(x4, x0, x1, x2, x3, 14); \
|
||||
ROUND(x0, x1, x2, x3, x4, 15); \
|
||||
ROUND(x1, x2, x3, x4, x0, 16); \
|
||||
ROUND(x2, x3, x4, x0, x1, 17); \
|
||||
ROUND(x3, x4, x0, x1, x2, 18); \
|
||||
ROUND(x4, x0, x1, x2, x3, 19); \
|
||||
ROUND(x0, x1, x2, x3, x4, 20); \
|
||||
ROUND(x1, x2, x3, x4, x0, 21); \
|
||||
ROUND(x2, x3, x4, x0, x1, 22); \
|
||||
ROUND(x3, x4, x0, x1, x2, 23); \
|
||||
ROUND(x4, x0, x1, x2, x3, 24); \
|
||||
ROUND(x0, x1, x2, x3, x4, 25); \
|
||||
ROUND(x1, x2, x3, x4, x0, 26); \
|
||||
ROUND(x2, x3, x4, x0, x1, 27); \
|
||||
ROUND(x3, x4, x0, x1, x2, 28); \
|
||||
ROUND(x4, x0, x1, x2, x3, 29); \
|
||||
ROUND(x0, x1, x2, x3, x4, 30); \
|
||||
ROUND(x1, x2, x3, x4, x0, 31)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,119 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2019 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include "sms4_lcl.h"
|
||||
#include <sm4.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static uint FK[4] = {
|
||||
0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc,
|
||||
};
|
||||
|
||||
static uint CK[32] = {
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
|
||||
};
|
||||
|
||||
|
||||
#define L32_(x) \
|
||||
((x) ^ \
|
||||
ROL32((x), 13) ^ \
|
||||
ROL32((x), 23))
|
||||
|
||||
#define ENC_ROUND(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \
|
||||
x4 = S32(x4); \
|
||||
x4 = x0 ^ L32_(x4); \
|
||||
*(rk + i) = x4
|
||||
|
||||
#define DEC_ROUND(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \
|
||||
x4 = S32(x4); \
|
||||
x4 = x0 ^ L32_(x4); \
|
||||
*(rk + 31 - i) = x4
|
||||
|
||||
void sms4_set_encrypt_key(sms4_key_t *key, const unsigned char user_key[16])
|
||||
{
|
||||
uint *rk = key->rk;
|
||||
uint x0, x1, x2, x3, x4;
|
||||
|
||||
x0 = GETU32(user_key) ^ FK[0];
|
||||
x1 = GETU32(user_key + 4) ^ FK[1];
|
||||
x2 = GETU32(user_key + 8) ^ FK[2];
|
||||
x3 = GETU32(user_key + 12) ^ FK[3];
|
||||
|
||||
#define ROUND ENC_ROUND
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
#undef ROUND
|
||||
|
||||
x0 = x1 = x2 = x3 = x4 = 0;
|
||||
}
|
||||
|
||||
void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char user_key[16])
|
||||
{
|
||||
uint *rk = key->rk;
|
||||
uint x0, x1, x2, x3, x4;
|
||||
|
||||
x0 = GETU32(user_key) ^ FK[0];
|
||||
x1 = GETU32(user_key + 4) ^ FK[1];
|
||||
x2 = GETU32(user_key + 8) ^ FK[2];
|
||||
x3 = GETU32(user_key + 12) ^ FK[3];
|
||||
|
||||
#define ROUND DEC_ROUND
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
#undef ROUND
|
||||
|
||||
x0 = x1 = x2 = x3 = x4 = 0;
|
||||
}
|
|
@ -0,0 +1,719 @@
|
|||
/**
|
||||
* 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 bn1 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 bignum.c
|
||||
* @brief arithmetic of big number
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <bignum.h>
|
||||
|
||||
sm9curve curve;
|
||||
// used in Montgomery Mult
|
||||
uint32_t qlow_reverse = 0x2f2ee42b; // power(2, 32) - (curve.q.word[0] 's reverse under power(2, 32))
|
||||
uint32_t Nlow_reverse = 0x51974b53; // power(2, 32) - (curve.N.word[0] 's reverse under power(2, 32))
|
||||
big8w q_2k; // (2^(256*2)) mod curve.q; used in big numbers' mult(Montgomery Mult)
|
||||
big8w N_2k; // (2^(256*2)) mod curve.N; used in big numbers' mult(Montgomery Mult)
|
||||
|
||||
/**
|
||||
* @brief This function is to print the big number in hex.
|
||||
*
|
||||
* @param bignum pointer of a big number
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
void Big8wPrint(big8w* bignum)
|
||||
{
|
||||
int i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
while (bignum->word[i] == 0 && i >= 0)
|
||||
i--;
|
||||
if (i < 0) {
|
||||
KPrintf("0x00\n");
|
||||
return;
|
||||
}
|
||||
|
||||
KPrintf("0x %08x", bignum->word[i]);
|
||||
|
||||
if(i--) // i > 0
|
||||
for (; i>=0; i--)
|
||||
KPrintf(" %08x", bignum->word[i]);
|
||||
|
||||
KPrintf("\n");
|
||||
}
|
||||
/**
|
||||
* @brief This function is to get the index of highest bit of highest word.
|
||||
*
|
||||
* @param bignum pointer of a big number
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
uint8_t Big8wHighestbit(big8w* bignum)
|
||||
{
|
||||
uint8_t i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
uint32_t elem;
|
||||
|
||||
while (bignum->word[i] == 0 && i >= 0)
|
||||
i--;
|
||||
elem = bignum->word[i];
|
||||
|
||||
i = 32;
|
||||
while(--i)
|
||||
if ((elem >> i) & 1)
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief This function is to judge if a big number is zero
|
||||
*
|
||||
* @param bignum pointer of a big number
|
||||
*
|
||||
* @return true if bignum == 0; else false
|
||||
*
|
||||
*/
|
||||
bool Big8wIsZero(big8w* bignum)
|
||||
{
|
||||
char i = 0;
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++)
|
||||
if (bignum->word[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief return bn1 >= bn2
|
||||
*
|
||||
* @param bn1 the first big number
|
||||
* @param bn2 the second big number
|
||||
*
|
||||
* @return true if bn1 >= bn2; false if bn1 < bn2
|
||||
*
|
||||
*/
|
||||
bool Big8wBigThan(big8w* bn1, big8w* bn2)
|
||||
{
|
||||
uint8_t i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
|
||||
for (; i; i--) {
|
||||
if (bn1->word[i] > bn2->word[i])
|
||||
return true;
|
||||
|
||||
else if (bn1->word[i] < bn2->word[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return bn1->word[i] >= bn2->word[i];
|
||||
}
|
||||
/**
|
||||
* @brief reutrn bn1 == bn2
|
||||
*
|
||||
* @param bn1 the first big number
|
||||
* @param bn2 the second big number
|
||||
*
|
||||
* @return true if bn1 == bn2; else false
|
||||
*
|
||||
*/
|
||||
bool Big8wEqual(big8w* bn1, big8w* bn2)
|
||||
{
|
||||
uint8_t i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
|
||||
for (; i; i--)
|
||||
if (bn1->word[i] != bn2->word[i])
|
||||
return false;
|
||||
|
||||
return bn1->word[i] == bn2->word[i];
|
||||
}
|
||||
/**
|
||||
* @brief compute (bn1 - bn2)%p
|
||||
*
|
||||
* @param bn1 the first big number, smaller than p
|
||||
* @param bn2 the second big number, smaller than p
|
||||
* @param p a big number, the module number
|
||||
*
|
||||
* @return ret, a big number
|
||||
*/
|
||||
big8w Big8wMinusMod(big8w bn1, big8w bn2, big8w p)
|
||||
{
|
||||
bool borrow = 0;
|
||||
char i = 0;
|
||||
big8w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
if (Big8wEqual(&bn2, &bn1))
|
||||
return ret;
|
||||
|
||||
else if (Big8wBigThan(&bn2, &bn1)) { // p - (bn2 - bn1)
|
||||
ret = Big8wMinusMod(bn2, bn1, p);
|
||||
ret = Big8wMinusMod(p, ret, p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
borrow = 0;
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++){
|
||||
ret.word[i] = bn1.word[i] - bn2.word[i] - borrow;
|
||||
borrow = (ret.word[i] < bn1.word[i] || ((ret.word[i] == bn1.word[i]) && borrow == 0)) ? 0 : 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief compute (bn1 + bn2)%p
|
||||
*
|
||||
* @param bn1 the first big number
|
||||
* @param bn2 the second big number
|
||||
* @param p a big number, the module number
|
||||
*
|
||||
* @return ret, a big number
|
||||
*
|
||||
*/
|
||||
big8w Big8wAddMod(big8w bn1, big8w bn2, big8w p)
|
||||
{
|
||||
bool flag = 0;
|
||||
uint8_t i = 0;
|
||||
big8w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++){
|
||||
ret.word[i] = bn1.word[i] + bn2.word[i] + flag;
|
||||
flag = (
|
||||
(ret.word[i] > bn1.word[i] && ret.word[i] > bn2.word[i] )
|
||||
|| ((ret.word[i]==bn1.word[i] ||ret.word[i]==bn2.word[i]) && flag == 0)
|
||||
) ? 0 : 1;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
// (2^(32*8)) + ret - p = (2^(32*8)-1) - (p - ret) + 1
|
||||
// ret = p - ret
|
||||
ret = Big8wMinusMod(p, ret, p);
|
||||
|
||||
// ret = (2^(32*8)-1) - (p - ret)
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++)
|
||||
ret.word[i] = 0xffffffff - ret.word[i];
|
||||
|
||||
// ret++
|
||||
i = 0;
|
||||
while (i < BIGNUMBER_SIZE_8WORD && ret.word[i] == 0xffffffff)
|
||||
i++;
|
||||
ret.word[i]++; // plus one
|
||||
if (i)
|
||||
while (--i)
|
||||
ret.word[i] = 0;
|
||||
}
|
||||
|
||||
if (Big8wBigThan(&ret, &p))
|
||||
ret = Big8wMinusMod(ret, p, p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief big number << (kround * 32 + rest), result store in big16w
|
||||
*
|
||||
* @param bignum a big number
|
||||
* @param kround (left shift bits) // 32
|
||||
* @param rest (left shift bits) % 32
|
||||
* @param length length of bignum, size = unsigned int
|
||||
* @param highestbit index of the highest bit of highest word of bignum, 0 <= highest <= 31
|
||||
*
|
||||
* @return ret, 16word big number
|
||||
*
|
||||
*/
|
||||
big16w Big16wLeftShift(big8w bignum, uint8_t kround, uint8_t rest, uint8_t length, uint8_t highestbit)
|
||||
{
|
||||
char i = 0;
|
||||
big16w ret;
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE * 2);
|
||||
|
||||
for (i = 0; i <= length; i++)
|
||||
ret.word[i + kround] = bignum.word[i];
|
||||
ret.length = length + kround;
|
||||
|
||||
if (rest) {
|
||||
if (rest + highestbit > 31)
|
||||
ret.length++;
|
||||
for (i = ret.length; i >kround; i--)
|
||||
ret.word[i] = ret.word[i] << rest | ret.word[i - 1] >> (32 - rest);
|
||||
ret.word[i] <<= rest;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief This function is to get the index of highest bit of highest word of a big number of 16word size.
|
||||
*
|
||||
* @param bignum16w pointer of a big number of 16word size.
|
||||
*
|
||||
* @return ret, unsigned char
|
||||
*
|
||||
*/
|
||||
uint8_t Big16wHighestbit(big16w bignum16w)
|
||||
{
|
||||
uint8_t ret = 31;
|
||||
uint32_t elem = bignum16w.word[bignum16w.length];
|
||||
|
||||
if (bignum16w.length == 0 && bignum16w.word[bignum16w.length] == 0)
|
||||
return 0;
|
||||
|
||||
while (true) {
|
||||
if (((elem >> ret) & 1) == 0)
|
||||
ret--;
|
||||
else
|
||||
return ret;
|
||||
} // end while
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief return bn1 >= bn2
|
||||
*
|
||||
* @param bn1 the first big number of 16word size.
|
||||
* @param bn2 the second big number of 16word size.
|
||||
*
|
||||
* @return true if bn1 >= bn2; else false
|
||||
*
|
||||
*/
|
||||
bool Big16wBigThan(big16w bn1, big16w bn2)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (bn1.length > bn2.length)
|
||||
return true;
|
||||
else if (bn1.length < bn2.length)
|
||||
return false;
|
||||
|
||||
for (i = bn1.length; i > 0; i--){
|
||||
if (bn1.word[i] > bn2.word[i])
|
||||
return true;
|
||||
else if (bn1.word[i] < bn2.word[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return bn1.word[0] >= bn2.word[0];
|
||||
}
|
||||
/**
|
||||
* @brief return (bn1 - bn2)
|
||||
*
|
||||
* @param bn1 the first big number of 16word size.
|
||||
* @param bn2 the second big number of 16word size.
|
||||
*
|
||||
* @return (bn1 - bn2), a big numbe of 16word size
|
||||
*
|
||||
*/
|
||||
big16w Big16wMinus(big16w bn1, big16w bn2)
|
||||
{
|
||||
bool borrow;
|
||||
char len = bn1.length;
|
||||
int i = 0;
|
||||
big16w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE * 2);
|
||||
|
||||
borrow = 0;
|
||||
for (i = 0; i <= bn1.length; i++){
|
||||
ret.word[i] = bn1.word[i] - bn2.word[i] - borrow;
|
||||
borrow = (ret.word[i] < bn1.word[i] || ((ret.word[i] == bn1.word[i]) && borrow == 0)) ? 0 : 1;
|
||||
}
|
||||
|
||||
i = bn1.length;
|
||||
while (ret.word[i] == 0)
|
||||
i--;
|
||||
ret.length = i;
|
||||
if (i < 0)
|
||||
ret.length = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief This function is only called by function H(), which is in topfunc.h
|
||||
* while(bignum16w.length > 7) // bignum16w > p
|
||||
* bignum16w = bignum16w - (p << gap) or bignum16w = (p << gap) - bignum16w, turn = !turn
|
||||
*
|
||||
* if (turn) // bignum16w == (p - bignum16w) mod p, bignum16w == (- ret) mod p
|
||||
* bignum16w = p - bignum16w
|
||||
*
|
||||
* @param bignum16w big number of 16word size.
|
||||
* @param p big number, the module number.
|
||||
*
|
||||
* @return bignum16w % p.
|
||||
*
|
||||
*/
|
||||
big8w Big16wmod8w(big16w bignum16w, big8w p)
|
||||
{
|
||||
bool turn = false;
|
||||
char plen = 7;
|
||||
char pbit = Big8wHighestbit(&p);
|
||||
int gap;
|
||||
big8w ret;
|
||||
big16w temp;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
while (p.word[plen] == 0)
|
||||
plen--;
|
||||
|
||||
while (bignum16w.length > 7){
|
||||
gap = bignum16w.length * 32 + Big16wHighestbit(bignum16w) - 255; // 255 = bitlen of p
|
||||
temp = Big16wLeftShift(p, gap >> 5, gap & 0x1f, plen, pbit);
|
||||
if (Big16wBigThan(bignum16w, temp))
|
||||
bignum16w = Big16wMinus(bignum16w, temp);
|
||||
else {
|
||||
bignum16w = Big16wMinus(temp, bignum16w);
|
||||
turn = !turn;
|
||||
}// end else
|
||||
}
|
||||
|
||||
for (gap = 7; gap >= 0; gap--)
|
||||
ret.word[gap] = bignum16w.word[gap];
|
||||
while (Big8wBigThan(&ret, &p))
|
||||
ret = Big8wMinusMod(ret, p, p);
|
||||
if (turn)
|
||||
ret = Big8wMinusMod(p, ret, p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief big number right shift
|
||||
*
|
||||
* @param bignum big number
|
||||
* @param round bit length of big number to right shift
|
||||
*
|
||||
* @return big number = (bignum >> round)
|
||||
*
|
||||
*/
|
||||
big8w Big8wRightShift(big8w bignum, uint8_t round)
|
||||
{
|
||||
uint8_t kround = round >> 5;
|
||||
uint8_t rest = round & 0x1f;
|
||||
char i;
|
||||
big8w ret;
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD - kround; i++)
|
||||
ret.word[i] = bignum.word[i + kround];
|
||||
|
||||
if (rest) {
|
||||
if (kround) {
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD - kround; i++) {
|
||||
ret.word[i] = (ret.word[i] >> rest) | (ret.word[i + 1] << (32 - rest));
|
||||
} // end for
|
||||
}else {
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD - 1; i++) {
|
||||
ret.word[i] = (ret.word[i] >> rest) | (ret.word[i + 1] << (32 - rest));
|
||||
} // end for
|
||||
ret.word[7] >>= rest;
|
||||
}
|
||||
} // end if
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief return (bignum + N)>>1. (bignum + N) is even. only called by Big8wReverse, more in Big8wReverse
|
||||
*
|
||||
* @param bignum the first big number
|
||||
* @param N the second big number
|
||||
*
|
||||
* @return a big number = (bignum + N) >> 1.
|
||||
*
|
||||
*/
|
||||
big8w PlusAndRightShiftOne(big8w bignum, big8w N)
|
||||
{
|
||||
bool flag = 0;
|
||||
uint8_t i = 0;
|
||||
big8w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++) {
|
||||
ret.word[i] = bignum.word[i] + N.word[i] + flag;
|
||||
|
||||
flag = (
|
||||
(ret.word[i] > bignum.word[i] && ret.word[i] > N.word[i])
|
||||
|| ((ret.word[i] == bignum.word[i] || ret.word[i] == N.word[i]) && flag == 0)
|
||||
) ? 0 : 1;
|
||||
}
|
||||
|
||||
ret = Big8wRightShift(ret, 1);
|
||||
if (flag)
|
||||
ret.word[7] |= 0x80000000;
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief get reverse of bignum under N; implemented with Stein algorithm.
|
||||
* Calls: Big8wRightShift, PlusAndRightShiftOne, Big8wEqual, Big8wMinusMod
|
||||
*
|
||||
* @param bignum a big number
|
||||
* @param N a big prime number
|
||||
*
|
||||
* @return a big number = (bignum)^(-1) mod N
|
||||
*
|
||||
*/
|
||||
big8w Big8wReverse(big8w bignum, big8w N)
|
||||
{
|
||||
bool flag1, flag2;
|
||||
big8w ret, zero, one, x1, y1, x2, y2, temp;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
memset(zero.word, 0x00, BIG8W_BYTESIZE);
|
||||
memset(one.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
one.word[0] = 1;
|
||||
|
||||
x1 = bignum, y1 = one;
|
||||
x2 = N, y2 = zero;
|
||||
|
||||
while (true){
|
||||
flag1 = ((x1.word[0]&1) == 0), flag2 = ((y1.word[0]&1) == 0);
|
||||
if (flag1 && flag2) {
|
||||
x1 = Big8wRightShift(x1, 1);
|
||||
y1 = Big8wRightShift(y1, 1);
|
||||
}
|
||||
else if (flag1 && !flag2) {
|
||||
x1 = Big8wRightShift(x1, 1);
|
||||
y1 = PlusAndRightShiftOne(y1, N);
|
||||
}
|
||||
if (Big8wEqual(&x1, &one))
|
||||
return y1;
|
||||
|
||||
flag1 = ((x2.word[0]&1) == 0), flag2 = ((y2.word[0]&1) == 0);
|
||||
if (flag1 && flag2) {
|
||||
x2 = Big8wRightShift(x2, 1);
|
||||
y2 = Big8wRightShift(y2, 1);
|
||||
}
|
||||
else if (flag1 && !flag2) {
|
||||
x2 = Big8wRightShift(x2, 1);
|
||||
y2 = PlusAndRightShiftOne(y2, N);
|
||||
}
|
||||
if (Big8wEqual(&x2, &one))
|
||||
return y2;
|
||||
|
||||
if (Big8wBigThan(&x1, &x2)) {
|
||||
x1 = Big8wMinusMod(x1, x2, N);
|
||||
y1 = Big8wMinusMod(y1, y2, N);
|
||||
if (Big8wEqual(&x1, &one))
|
||||
return y1;
|
||||
}
|
||||
else {
|
||||
x2 = Big8wMinusMod(x2, x1, N);
|
||||
y2 = Big8wMinusMod(y2, y1, N);
|
||||
if (Big8wEqual(&x2, &one))
|
||||
return y2;
|
||||
}
|
||||
|
||||
} // end while
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief return bn1 >= bn2
|
||||
*
|
||||
* @param bn1 string of unsigned int, length <= BIGNUMBER_SIZE + 1.
|
||||
* @param bn2 string of unsigned int, length <= BIGNUMBER_SIZE + 1.
|
||||
*
|
||||
* @return true if bn1 >= bn2; else false
|
||||
*
|
||||
*/
|
||||
bool U32CMP(uint32_t* bn1, uint32_t* bn2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = BIGNUMBER_SIZE_8WORD + 1; i; i--) {
|
||||
if (bn1[i] > bn2[i])
|
||||
return true;
|
||||
else if (bn1[i] < bn2[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return bn1[0] >= bn2[0];
|
||||
}
|
||||
/**
|
||||
* @brief This function is to compute a big number multiply a unsinged int number.
|
||||
*
|
||||
* @param bignum big number
|
||||
* @param elem unsigned int
|
||||
* @param ret pointer of a string of unsigned int, length <= BIGNUMBER_SIZE_WORD + 2. store the result.
|
||||
*
|
||||
* @result ret = bignum * elem,
|
||||
*
|
||||
*/
|
||||
void Big8wMultNum(big8w bignum, uint32_t elem, uint32_t* ret)
|
||||
{
|
||||
char i = 0;
|
||||
uint32_t overflow = 0;
|
||||
uint64_t temp;
|
||||
|
||||
memset(ret, 0x00, sizeof(uint32_t) * (BIGNUMBER_SIZE_8WORD + 2));
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++) {
|
||||
temp = ((uint64_t)elem * (uint64_t)bignum.word[i]) + (uint64_t)overflow;
|
||||
ret[i] = temp;
|
||||
overflow = temp >> 32;
|
||||
}
|
||||
|
||||
ret[BIGNUMBER_SIZE_8WORD] = overflow;
|
||||
}
|
||||
/**
|
||||
* @brief add two unsigned int strings.
|
||||
*
|
||||
* @param bn1 string of unsigned int, lenght < BIGNUMBER_SIZE_8WORD + 2
|
||||
* @param bn2 string of unsigned int, lenght < BIGNUMBER_SIZE_8WORD + 2
|
||||
* @param ret string of unsigned int, lenght < BIGNUMBER_SIZE_8WORD + 2, store the result
|
||||
*
|
||||
* @result ret, string of unsigned int
|
||||
*/
|
||||
void U32Add(uint32_t* bn1, uint32_t* bn2, uint32_t* ret)
|
||||
{
|
||||
char i;
|
||||
bool overflow = 0;
|
||||
uint64_t temp;
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD + 2; i++){
|
||||
temp = (uint64_t)bn1[i] + (uint64_t)bn2[i] + (uint64_t)overflow;
|
||||
ret[i] = temp;
|
||||
overflow = temp >> 32;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief two unsigned int strings run minus.
|
||||
*
|
||||
* @param bn1 the first string of unsigned int, lenght <= BIGNUMBER_SIZE_8WORD + 2
|
||||
* @param bn2 the second string of unsigned int, lenght <= BIGNUMBER_SIZE_8WORD + 2
|
||||
* @param ret the result string of unsigned int, lenght <= BIGNUMBER_SIZE_8WORD + 2, store the result
|
||||
*
|
||||
* @result ret
|
||||
*/
|
||||
void U32Minus(uint32_t* bn1, uint32_t* bn2, uint32_t* ret)
|
||||
{
|
||||
char i;
|
||||
bool borrow = 0, newborrow;
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD + 2; i++){
|
||||
newborrow = (uint64_t)bn1[i] < ((uint64_t)bn2[i] + borrow);
|
||||
ret[i] = bn1[i] - bn2[i] - borrow;
|
||||
borrow = newborrow;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Montogery multyply algorithm; Calls: Big8wMultNum, U32CMP, U32Add, U32Minus; Called By: Big8wMultMod
|
||||
* montmult(bn1, bn2, p) = bn1 * bn2 * (2^(32*8)) mod p
|
||||
*
|
||||
* @param bn1 the first big number
|
||||
* @param bn2 the second big number
|
||||
* @param p big number, the module number
|
||||
* @param fill unsigned int, precomputed number
|
||||
* @param ret pointer of a string of unsigned int, store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void Big8wMontMult(big8w bn1, big8w bn2, big8w p, uint32_t fill, uint32_t* ret)
|
||||
{
|
||||
int i;
|
||||
int numindex = BIGNUMBER_SIZE_8WORD - 1;
|
||||
uint32_t temp[BIGNUMBER_SIZE_8WORD + 1 + 1]; // big8w mult uint32_t and add overflow
|
||||
uint32_t elem, time;
|
||||
|
||||
memset(temp, 0x00, sizeof(uint32_t) * (BIGNUMBER_SIZE_8WORD + 1 + 1));
|
||||
memset(ret, 0x00, sizeof(uint32_t) * (BIGNUMBER_SIZE_8WORD + 1 + 1));
|
||||
|
||||
while (bn2.word[numindex] == 0)
|
||||
numindex--;
|
||||
if (numindex < 0)
|
||||
return;
|
||||
|
||||
for (numindex = 0; numindex < BIGNUMBER_SIZE_8WORD; numindex++){
|
||||
elem = bn2.word[numindex];
|
||||
Big8wMultNum(bn1, elem, temp);
|
||||
U32Add(temp, ret, ret);
|
||||
Big8wMultNum(p, fill*ret[0], temp);
|
||||
U32Add(temp, ret, ret);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD + 1; i++)
|
||||
{ // ret.word[0] = 0, (ret >> 32) == ret * (2^(-32)) mod p
|
||||
ret[i] = ret[i + 1];
|
||||
}
|
||||
ret[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++)
|
||||
temp[i] = p.word[i];
|
||||
temp[i] = 0, temp[i + 1] = 0;
|
||||
|
||||
if (U32CMP(ret, temp))
|
||||
U32Minus(ret, temp, ret);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief return (bn1*bn2 mod p); call twice Montogery multiply algorithm. Only suitable for sm9, the input big8w p is q or N.
|
||||
* montmult(A, B, p) = A * B * (2^(-32*8)) mod p, which can be computed fastly.
|
||||
* so multmod(A, B, p) can be computed by:
|
||||
* ret = montmult(A, B, p) = A*B*(2^(-256)) mod p
|
||||
* ret = montmult(ret, 2^(256*2), p) = ret * 2^(256*2) * (2^(-256)) mod p (computed fastly)
|
||||
* = A * B * (2^(-256)) * (2^(256*2)) * (2^(-256)) mod p = A * B mod p (verify the algorithm)
|
||||
* N_2k = (2^(256*2)) mod curve.N; q_2k = (2^(256*2)) mod curve.q
|
||||
* fill = (2^32 - ((p.word[0])^(-1) mod (2^32))).
|
||||
* fill is precalculated, module number p could be prime number curve.q or curve.N
|
||||
* more details see the theory of Montogery multiply algorithm
|
||||
*
|
||||
* @param bn1 the first big number
|
||||
* @param bn2 the second big number
|
||||
* @param p big number, the module number.
|
||||
*
|
||||
* @return ret, big number, ret = bn1 * bn2 mod p.
|
||||
*
|
||||
*/
|
||||
big8w Big8wMultMod(big8w bn1, big8w bn2, big8w p)
|
||||
{
|
||||
bool flag; // to decide use N_2k or q_2k
|
||||
char i;
|
||||
uint32_t res[BIGNUMBER_SIZE_8WORD + 1 + 1];
|
||||
uint32_t fill;
|
||||
big8w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
if (Big8wEqual(&p, &curve.q)){
|
||||
fill = qlow_reverse;
|
||||
flag = 1;
|
||||
}
|
||||
else {
|
||||
fill = Nlow_reverse;
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
if (Big8wIsZero(&bn1) || Big8wIsZero(&bn2))
|
||||
return ret;
|
||||
|
||||
Big8wMontMult(bn1, bn2, p, fill, res);
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++)
|
||||
ret.word[i] = res[i];
|
||||
|
||||
if (flag)
|
||||
Big8wMontMult(ret, q_2k, p, fill, res);
|
||||
else
|
||||
Big8wMontMult(ret, N_2k, p, fill, res);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++)
|
||||
ret.word[i] = res[i];
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* 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 join.c
|
||||
* @brief convert data type and join string
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
#include <join.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief convert big8w to char string and insert into string, start from startindex
|
||||
*
|
||||
* @param bignum a big number
|
||||
* @param string a string of unsigned char
|
||||
* @param startindex the start index of string convert to bignum
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
void Big8wIntou8string(big8w* bignum, uint8_t* string, uint32_t startindex)
|
||||
{
|
||||
int index;
|
||||
uint32_t elem;
|
||||
|
||||
for (index = BIGNUMBER_SIZE_8WORD - 1; index >= 0; index--) {
|
||||
elem = bignum->word[index];
|
||||
string[startindex++] = (uint8_t)(elem >> 24);
|
||||
string[startindex++] = (uint8_t)(elem >> 16);
|
||||
string[startindex++] = (uint8_t)(elem >> 8);
|
||||
string[startindex++] = (uint8_t)(elem);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief convert q12 to char string and insert into string, start from startindex
|
||||
*
|
||||
* @param num a pointer of a number in Fq12
|
||||
* @param string a string of unsigned int
|
||||
* @param startindex the start index of string to insert.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
void Q12Intou8string(q12* num, uint8_t* string, uint32_t startindex)
|
||||
{
|
||||
Big8wIntou8string(&num->high.high.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->high.high.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->high.low.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->high.low.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->mid.high.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->mid.high.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->mid.low.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->mid.low.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->low.high.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->low.high.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->low.low.high, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&num->low.low.low, string, startindex);
|
||||
startindex += BIG8W_BYTESIZE;
|
||||
}
|
||||
/**
|
||||
* @brief convert unsigned char string to a point in group G1.
|
||||
*
|
||||
* @param string unsinged char string
|
||||
* @param ret pointer of a point in group G1
|
||||
*
|
||||
* @return ret
|
||||
*
|
||||
*/
|
||||
void U8stringToG1point(uint8_t* string, G1point *ret)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 1; i < BIGNUMBER_SIZE_8WORD + 1; i++)
|
||||
ret->x.word[BIGNUMBER_SIZE_8WORD - i] = GETU32((string + 4*(i-1)));
|
||||
|
||||
for (i = 1; i < BIGNUMBER_SIZE_8WORD + 1; i++)
|
||||
ret->y.word[BIGNUMBER_SIZE_8WORD - i] = GETU32((string + BIG8W_BYTESIZE + 4*(i-1)));
|
||||
}
|
||||
/**
|
||||
* @brief join ID and hid
|
||||
*
|
||||
* @param ID id, unsigned char string
|
||||
* @param hid hid(0x01, 0x02, 0x03), unsigned char, defined in SM9
|
||||
* @param ret unsigned char string, store the result of joined ID and hid
|
||||
*
|
||||
* @return ret
|
||||
*
|
||||
*/
|
||||
void JoinIDhid(uint8_t* ID, uint8_t IDlen, uint8_t hid, uint8_t* ret)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < IDlen; i++)
|
||||
ret[i] = ID[i];
|
||||
|
||||
ret[i] = hid;
|
||||
}
|
||||
/**
|
||||
* @brief join message and w(q12 number).
|
||||
*
|
||||
* @param message message, unsigned char string
|
||||
* @param msglen length of message, byte size
|
||||
* @param w pointer of a number in Fq12
|
||||
* @param ret unsigned char string, store the result
|
||||
*
|
||||
* @return ret
|
||||
*
|
||||
*/
|
||||
void JoinMsgW(uint8_t* message, uint32_t msglen, q12* w, uint8_t* ret)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < msglen; i++)
|
||||
ret[i] = message[i];
|
||||
|
||||
Q12Intou8string(w, ret, msglen);
|
||||
}
|
||||
/**
|
||||
* @brief join IDA, IDB, RA, RB, g1, g2, g3, defined in SM9
|
||||
*
|
||||
* @param ID_Challenger id of challenger, unsigned char string
|
||||
* @param ID_Challenger_len length of the id of challenger, byte size, unsigned char
|
||||
* @param ID_Responser id of responser, unsigned char string
|
||||
* @param ID_Responser_len length of the id of responser, byte size, unsigned char
|
||||
* @param R_Challenger pointer of a point in group G1
|
||||
* @param R_Responser pointer of a point in group G1
|
||||
* @param g1 pointer of a number in Fq12, defined in SM9
|
||||
* @param g2 pointer of a number in Fq12, defined in SM9
|
||||
* @param g3 pointer of a number in Fq12, defined in SM9
|
||||
* @param ret unsigned char string, store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void JoinIDAIDBRARBg123(
|
||||
uint8_t *ID_Challenger, uint8_t ID_Challenger_len,
|
||||
uint8_t *ID_Responser, uint8_t ID_Responser_len,
|
||||
G1point* R_Challenger, G1point* R_Responser,
|
||||
q12 *g1, q12 *g2, q12 *g3,
|
||||
uint8_t* ret)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t index = 0;
|
||||
|
||||
index = 0;
|
||||
while (index < ID_Challenger_len)
|
||||
ret[i++] = ID_Challenger[index++];
|
||||
index = 0;
|
||||
while (index < ID_Responser_len)
|
||||
ret[i++] = ID_Responser[index++];
|
||||
|
||||
Big8wIntou8string(&R_Challenger->x, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&R_Challenger->y, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&R_Responser->x, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&R_Responser->y, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Q12Intou8string(g1, ret, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
|
||||
Q12Intou8string(g2, ret, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
|
||||
Q12Intou8string(g3, ret, i);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief join C, w, ID, defined in SM9
|
||||
*
|
||||
* @param C a pointer of a point in group G1
|
||||
* @param w a pointer of a number in Fq12
|
||||
* @param ID unsinged char string
|
||||
* @param IDlen length of ID, byte size, unsinged char
|
||||
* @param ret unsinged char string , store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void JoinCwID(G1point* C, q12* w, uint8_t* ID, uint8_t IDlen, uint8_t* ret)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
Big8wIntou8string(&C->x, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
Big8wIntou8string(&C->y, ret, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Q12Intou8string(w, ret, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
|
||||
while (index < IDlen)
|
||||
ret[i++] = ID[index++];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief msg xor K; u8string xor u8string
|
||||
*
|
||||
* @param msg message, unsigned char string
|
||||
* @param msglen length of message, byte size, unsigned int
|
||||
* @param K produced by KDF(), unsigned char string
|
||||
* @param ret unsigned char string, store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void XOR(unsigned char* msg, uint32_t msglen, unsigned char* K, unsigned char* ret)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < msglen; i++)
|
||||
ret[i] = msg[i] ^ K[i];
|
||||
|
||||
}
|
|
@ -0,0 +1,970 @@
|
|||
/*
|
||||
* 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 qn.c
|
||||
* @brief arithmetic in extention field, and arithmetic in group G2, frobenius and LastPower in BiLinearPairing
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
#include <qn.h>
|
||||
|
||||
big8w t; // sm9 ecc parameter
|
||||
big8w qnr; // (-1/2) mod curve.q
|
||||
big8w frobenius_constant_1[12];
|
||||
big8w frobenius_constant_2[12];
|
||||
/**
|
||||
* @brief print the point in group G2
|
||||
*
|
||||
* @param point a pointer of point in group G2
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
void G2pointPrint(G2point* point)
|
||||
{
|
||||
Big8wPrint(&point->x.high);
|
||||
Big8wPrint(&point->x.low);
|
||||
Big8wPrint(&point->y.high);
|
||||
Big8wPrint(&point->y.low);
|
||||
}
|
||||
/**
|
||||
* @brief print a number in Fq12
|
||||
*
|
||||
* @param number a pointer of number in Fq12
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
void Q12Print(q12* number)
|
||||
{
|
||||
Big8wPrint(&number->high.high.high);
|
||||
Big8wPrint(&number->high.high.low);
|
||||
Big8wPrint(&number->high.low.high);
|
||||
Big8wPrint(&number->high.low.low);
|
||||
|
||||
Big8wPrint(&number->mid.high.high);
|
||||
Big8wPrint(&number->mid.high.low);
|
||||
Big8wPrint(&number->mid.low.high);
|
||||
Big8wPrint(&number->mid.low.low);
|
||||
|
||||
Big8wPrint(&number->low.high.high);
|
||||
Big8wPrint(&number->low.high.low);
|
||||
Big8wPrint(&number->low.low.high);
|
||||
Big8wPrint(&number->low.low.low);
|
||||
}
|
||||
/**
|
||||
* @brief convert q12 to big_12big
|
||||
*
|
||||
* @param num pointer of number in Fq12
|
||||
* @param ret pointer of big_12big, store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void Q12To12big(q12* num, big_12big* ret)
|
||||
{
|
||||
ret->word[0] = num->high.high.high;
|
||||
ret->word[1] = num->high.high.low;
|
||||
ret->word[2] = num->high.low.high;
|
||||
ret->word[3] = num->high.low.low;
|
||||
|
||||
ret->word[4] = num->mid.high.high;
|
||||
ret->word[5] = num->mid.high.low;
|
||||
ret->word[6] = num->mid.low.high;
|
||||
ret->word[7] = num->mid.low.low;
|
||||
|
||||
ret->word[8] = num->low.high.high;
|
||||
ret->word[9] = num->low.high.low;
|
||||
ret->word[10] = num->low.low.high;
|
||||
ret->word[11] = num->low.low.low;
|
||||
}
|
||||
/**
|
||||
* @brief set a number in Fq12 to 0
|
||||
*
|
||||
* @param num pointer of a number in Fq12
|
||||
*
|
||||
* @resulr num
|
||||
*
|
||||
*/
|
||||
void Q2Zero(q2* num)
|
||||
{
|
||||
memset(num->high.word, 0x00, BIG8W_BYTESIZE);
|
||||
memset(num->low.word, 0x00, BIG8W_BYTESIZE);
|
||||
}
|
||||
/**
|
||||
* @brief set a number in Fq4 to 0
|
||||
*
|
||||
* @param num number in Fq4
|
||||
*
|
||||
* @result num
|
||||
*
|
||||
*/
|
||||
void Q4Zero(q4* num)
|
||||
{
|
||||
Q2Zero(&num->high);
|
||||
Q2Zero(&num->low);
|
||||
}
|
||||
/**
|
||||
* @brief set a number in Fq12 to 0
|
||||
*
|
||||
* @param num pointer of a number in Fq12
|
||||
*
|
||||
* @result num
|
||||
*
|
||||
*/
|
||||
void Q12Zero(q12* num)
|
||||
{
|
||||
Q4Zero(&num->high);
|
||||
Q4Zero(&num->mid);
|
||||
Q4Zero(&num->low);
|
||||
}
|
||||
/**
|
||||
* @brief return num1 == num2
|
||||
*
|
||||
* @param num1 pointer of the first number in Fq2
|
||||
* @param num2 pointer of the second number in Fq2
|
||||
*
|
||||
* @return true if num1 == num2; else false
|
||||
*
|
||||
*/
|
||||
bool Q2Equal(q2* num1, q2* num2)
|
||||
{
|
||||
return Big8wEqual(&num1->high, &num2->high)
|
||||
&& Big8wEqual(&num1->low, &num2->low);
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 + num2)
|
||||
*
|
||||
* @param num1 the first number in Fq2
|
||||
* @param num2 the second number in Fq2
|
||||
*
|
||||
* @return ret, a number in Fq2, ret = num1 + num2.
|
||||
*/
|
||||
q2 Q2Add(q2 num1, q2 num2)
|
||||
{
|
||||
q2 ret;
|
||||
|
||||
ret.high = Big8wAddMod(num1.high, num2.high, curve.q);
|
||||
ret.low = Big8wAddMod(num1.low, num2.low, curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 - num2)
|
||||
*
|
||||
* @param num1 the first number in Fq2
|
||||
* @param num2 the second number in Fq2
|
||||
*
|
||||
* @return ret, a number in Fq2, ret = num1 - num2.
|
||||
*/
|
||||
q2 Q2Minus(q2 num1, q2 num2)
|
||||
{
|
||||
q2 ret;
|
||||
|
||||
ret.high = Big8wMinusMod(num1.high, num2.high, curve.q);
|
||||
ret.low = Big8wMinusMod(num1.low, num2.low, curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
* set num1 = (a, b), num2 = (c, d), num1*num2 = (a*d + b*c, b*d - 2*a*c)......(high, low)
|
||||
* Toom-Cook: (a*d + b*c) = (a + b)(c + d) - a*c - b*d
|
||||
* Calls: Big8wMultMod, Big8wAddMod, Big8wMinusMod
|
||||
* Called By: G2pointAdd, Q4Mult, Q2Reverse and more
|
||||
* @param num1 the first number in Fq2
|
||||
* @param num2 the second number in Fq2
|
||||
*
|
||||
* @return ret, a number in Fq2, ret = num1 * num2
|
||||
*
|
||||
*/
|
||||
q2 Q2Mult(q2 num1, q2 num2)
|
||||
{ // num1 = (a1, a0), num2 = (b1, b0).....(high, low)
|
||||
q2 ret;
|
||||
big8w a0b0, a1b1;
|
||||
// Toom-Cook
|
||||
a0b0 = Big8wMultMod(num1.low, num2.low, curve.q);
|
||||
a1b1 = Big8wMultMod(num1.high, num2.high, curve.q);
|
||||
|
||||
ret.high = Big8wMultMod(
|
||||
Big8wAddMod(num1.high, num1.low, curve.q),
|
||||
Big8wAddMod(num2.high, num2.low, curve.q),
|
||||
curve.q);
|
||||
|
||||
ret.high = Big8wMinusMod(
|
||||
ret.high,
|
||||
Big8wAddMod(a0b0, a1b1, curve.q),
|
||||
curve.q);
|
||||
|
||||
ret.low = Big8wMinusMod(
|
||||
a0b0,
|
||||
Big8wAddMod(a1b1, a1b1, curve.q),
|
||||
curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief num1 = (a, b), num2 = (c, d), num1*num2*u = (b*d - 2*a*c, -2*(a*d +b*c)). compare Q2Mult
|
||||
*
|
||||
* @param num1 the first number in Fq2
|
||||
* @param num2 the second number in Fq2
|
||||
*
|
||||
* @return ret, a number in Fq2; ret = a * b * u
|
||||
*
|
||||
*/
|
||||
q2 Q2MultFlag(q2 num1, q2 num2)
|
||||
{
|
||||
q2 ret = Q2Mult(num1, num2);
|
||||
big8w temp = ret.high;
|
||||
|
||||
ret.high = ret.low;
|
||||
ret.low = Big8wMinusMod(
|
||||
curve.q,
|
||||
Big8wAddMod(temp, temp, curve.q), curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief num = (a, b), num^(-1) = ((-a)/(b*b +2*a*a), b/(b*b, 2*a*a))
|
||||
*
|
||||
* @param num number in Fq2
|
||||
*
|
||||
* @return ret, number in Fq2, ret = num^(-1).
|
||||
*
|
||||
*/
|
||||
q2 Q2Reverse(q2 num)
|
||||
{
|
||||
big8w temp;
|
||||
q2 ret;
|
||||
|
||||
temp = Big8wMultMod(num.high, num.high, curve.q); // a*a
|
||||
temp = Big8wAddMod(temp, temp, curve.q); // 2*a*a
|
||||
temp = Big8wAddMod(temp,
|
||||
Big8wMultMod(num.low, num.low, curve.q), curve.q); // (b*b +2*a*a)
|
||||
temp = Big8wReverse(temp, curve.q); // (1/(b*b + 2*a*a))
|
||||
|
||||
ret.high = Big8wMinusMod(curve.q, num.high, curve.q); // (-a)
|
||||
ret.high = Big8wMultMod(ret.high, temp, curve.q);
|
||||
ret.low = Big8wMultMod(num.low, temp, curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (-num);(-num.high, -num.low) mod curve.q = (curve.q - num.high, curve.q - num.low)
|
||||
*
|
||||
* @param num number in Fq2
|
||||
*
|
||||
* @return ret, a number in Fq2
|
||||
*
|
||||
*/
|
||||
q2 Q2Negate(q2 num)
|
||||
{
|
||||
num.high = Big8wMinusMod(curve.q, num.high, curve.q);
|
||||
num.low = Big8wMinusMod(curve.q, num.low, curve.q);
|
||||
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param num number in Fq2
|
||||
*
|
||||
* @return num
|
||||
*
|
||||
*/
|
||||
q2 Q2Txx(q2 num)
|
||||
{
|
||||
big8w temp;
|
||||
|
||||
temp = num.high;
|
||||
num.high = num.low;
|
||||
num.low = Big8wMinusMod(curve.q, temp, curve.q);
|
||||
num.low = Big8wAddMod(num.low, num.low, curve.q);
|
||||
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @brief add of two points in group G2
|
||||
*
|
||||
* @param point1 the first point in group G2
|
||||
* @param point2 the second point in group G2
|
||||
*
|
||||
* @return ret, a point in group G2
|
||||
*
|
||||
*/
|
||||
G2point G2PointAdd(G2point point1, G2point point2)
|
||||
{
|
||||
q2 temp, lambda;
|
||||
G2point ret;
|
||||
|
||||
memset(&temp, 0x00, BIG8W_BYTESIZE * 2);
|
||||
|
||||
// temp = zero
|
||||
// infinite point judge
|
||||
if (Q2Equal(&point1.x, &temp) && Q2Equal(&point1.y, &temp))
|
||||
return point2;
|
||||
else if (Q2Equal(&point2.x, &temp) && Q2Equal(&point2.y, &temp))
|
||||
return point1;
|
||||
|
||||
if (Big8wEqual(&point1.x.high, &point2.x.high)
|
||||
&& Big8wEqual(&point1.x.low, &point2.x.low)) { // x1 = x2
|
||||
|
||||
if (!Big8wEqual(&point1.y.high, &point2.y.high)
|
||||
|| !Big8wEqual(&point1.y.low, &point2.y.low)) // y1 != y2 (y1 = -y2)
|
||||
{
|
||||
memset(&ret, 0x00, BIG8W_BYTESIZE * 4);
|
||||
return ret; // ret = O
|
||||
}
|
||||
|
||||
temp = Q2Mult(point1.x, point1.x);
|
||||
|
||||
lambda = Q2Add(temp, temp);
|
||||
lambda = Q2Add(lambda, temp);
|
||||
lambda = Q2Mult(lambda, Q2Reverse(Q2Add(point1.y, point1.y)));
|
||||
}
|
||||
|
||||
else {
|
||||
lambda = Q2Mult(
|
||||
Q2Minus(point1.y, point2.y),
|
||||
Q2Reverse(Q2Minus(point1.x, point2.x)));
|
||||
}
|
||||
|
||||
ret.x = Q2Mult(lambda, lambda);
|
||||
ret.x = Q2Minus(ret.x, point1.x);
|
||||
ret.x = Q2Minus(ret.x, point2.x);
|
||||
|
||||
ret.y = Q2Minus(point1.x, ret.x);
|
||||
ret.y = Q2Mult(lambda, ret.y);
|
||||
ret.y = Q2Minus(ret.y, point1.y);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief mult point in group G2. (num * point)
|
||||
*
|
||||
* @param num big number, num > 0
|
||||
* @param point point in group G2
|
||||
*
|
||||
* @return ret, a point in group G2
|
||||
*
|
||||
*/
|
||||
G2point G2PointMult(big8w num, G2point point)
|
||||
{
|
||||
bool flag = 0;
|
||||
int i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
int index = Big8wHighestbit(&num);
|
||||
uint32_t elem;
|
||||
G2point ret = point, temp = point;
|
||||
|
||||
while (num.word[i] == 0)
|
||||
i--;
|
||||
elem = num.word[i];
|
||||
|
||||
index--;
|
||||
while (index >= 0) {
|
||||
flag = (elem >> (index--)) & 1;
|
||||
ret = G2PointAdd(temp, temp);
|
||||
if (flag)
|
||||
ret = G2PointAdd(ret, point);
|
||||
temp = ret;
|
||||
}
|
||||
|
||||
i--;
|
||||
for (; i >= 0; i--) {
|
||||
elem = num.word[i];
|
||||
index = 31;
|
||||
|
||||
while (index >= 0) {
|
||||
flag = (elem >> (index--)) & 1;
|
||||
ret = G2PointAdd(temp, temp);
|
||||
if (flag)
|
||||
ret = G2PointAdd(ret, point);
|
||||
temp = ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 + num2)
|
||||
*
|
||||
* @param num1 the first number in Fq4
|
||||
* @param num2 the second number in Fq4
|
||||
*
|
||||
* @return ret, a number in Fq4, ret = (num1 + num2)
|
||||
*
|
||||
*/
|
||||
q4 Q4Add(q4 num1, q4 num2)
|
||||
{
|
||||
q4 ret;
|
||||
|
||||
ret.high = Q2Add(num1.high, num2.high);
|
||||
ret.low = Q2Add(num1.low, num2.low);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 - num2)
|
||||
*
|
||||
* @param num1 the first number in Fq4
|
||||
* @param num2 the second number in Fq4
|
||||
*
|
||||
* @return ret, a number in Fq4, ret = (num1 - num2)
|
||||
*
|
||||
*/
|
||||
q4 Q4Minus(q4 num1, q4 num2)
|
||||
{
|
||||
q4 ret;
|
||||
|
||||
ret.high = Q2Minus(num1.high, num2.high);
|
||||
ret.low = Q2Minus(num1.low, num2.low);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief num1 * num2; num1, num2 are numbers in Fq4, the way to compute is similar to Q2Mult
|
||||
* q4 num = (num1, num2), similar to Q2Mult, except num1 = (a1, a0), a0, a1 is big8w
|
||||
*
|
||||
* @param num1 the first number in Fq4
|
||||
* @param num2 the second number in Fq4
|
||||
*
|
||||
* @return ret, a number in Fq4
|
||||
*/
|
||||
q4 Q4Mult(q4 num1, q4 num2)
|
||||
{// num1 = (a1, a0), num2 = (b1, b0). left high value
|
||||
q4 ret;
|
||||
q2 a0b0, a1b1;
|
||||
|
||||
// Toom-Cook
|
||||
a1b1 = Q2Mult(num1.high, num2.high);
|
||||
a0b0 = Q2Mult(num1.low, num2.low);
|
||||
|
||||
ret.high = Q2Mult(
|
||||
Q2Add(num1.high, num1.low),
|
||||
Q2Add(num2.high, num2.low));
|
||||
|
||||
ret.high = Q2Minus(
|
||||
ret.high,
|
||||
Q2Add(a0b0, a1b1));
|
||||
|
||||
ret.low.high = Big8wAddMod(a0b0.high, a1b1.low, curve.q);
|
||||
ret.low.low = Big8wMinusMod(
|
||||
a0b0.low,
|
||||
Big8wAddMod(a1b1.high, a1b1.high, curve.q),
|
||||
curve.q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return num1 * num2 * u; num1, num2 are numbers in Fq4
|
||||
*
|
||||
* @param num1 the first number in Fq4
|
||||
* @param num2 the second number in Fq4
|
||||
*
|
||||
* @return ret, a number in Fq4
|
||||
*
|
||||
*/
|
||||
q4 Q4MultFlag(q4 num1, q4 num2)
|
||||
{
|
||||
q4 ret;
|
||||
|
||||
ret.high = Q2Add(
|
||||
Q2Mult(num1.low, num2.low),
|
||||
Q2MultFlag(num1.high, num2.high));
|
||||
ret.low = Q2Add(
|
||||
Q2MultFlag(num1.high, num2.low),
|
||||
Q2MultFlag(num1.low, num2.high));
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param num number in Fq4
|
||||
*
|
||||
* @return ret, a number in Fq4
|
||||
*
|
||||
*/
|
||||
q4 Q4Txx(q4 num)
|
||||
{
|
||||
q2 temp;
|
||||
|
||||
temp = num.high;
|
||||
num.high = num.low;
|
||||
num.low = Q2Txx(temp);
|
||||
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @brief return (-num), similar to Q2Negate
|
||||
*
|
||||
* @param num a number in Fq4
|
||||
*
|
||||
* @return num, a number in Fq4
|
||||
*
|
||||
*/
|
||||
q4 Q4Negate(q4 num)
|
||||
{
|
||||
num.high = Q2Negate(num.high);
|
||||
num.low = Q2Negate(num.low);
|
||||
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @brief return num^(-1)
|
||||
*
|
||||
* @param num number in Fq4
|
||||
*
|
||||
* @return num, number in Fq4
|
||||
*
|
||||
*/
|
||||
q4 Q4Reverse(q4 num)
|
||||
{
|
||||
q2 t1, t2;
|
||||
|
||||
t1 = Q2Mult(num.low, num.low);
|
||||
t2 = Q2Mult(num.high, num.high);
|
||||
t2 = Q2Txx(t2);
|
||||
t1 = Q2Minus(t1, t2);
|
||||
t1 = Q2Reverse(t1);
|
||||
num.low = Q2Mult(num.low, t1);
|
||||
t1 = Q2Negate(t1);
|
||||
num.high = Q2Mult(num.high, t1);
|
||||
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 * num2);
|
||||
*
|
||||
* @param num1 the first number in Fq12
|
||||
* @param num2 the second number in Fq12
|
||||
*
|
||||
* @return a number in Fq12
|
||||
*
|
||||
*/
|
||||
q12 Q12MultMod(q12 num1, q12 num2)
|
||||
{
|
||||
q12 ret;
|
||||
|
||||
ret.high = Q4Add(
|
||||
Q4Mult(num1.high, num2.low),
|
||||
Q4Mult(num1.mid, num2.mid));
|
||||
|
||||
ret.high = Q4Add(
|
||||
ret.high,
|
||||
Q4Mult(num1.low, num2.high));
|
||||
|
||||
ret.mid = Q4Add(
|
||||
Q4Mult(num1.low, num2.mid),
|
||||
Q4Mult(num1.mid, num2.low));
|
||||
|
||||
ret.mid = Q4Add(
|
||||
ret.mid,
|
||||
Q4MultFlag(num1.high, num2.high));
|
||||
|
||||
ret.low = Q4Add(
|
||||
Q4MultFlag(num1.high, num2.mid),
|
||||
Q4MultFlag(num1.mid, num2.high));
|
||||
|
||||
ret.low = Q4Add(
|
||||
ret.low,
|
||||
Q4Mult(num1.low, num2.low));
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 - num2)
|
||||
*
|
||||
* @param num1 the first number in Fq12
|
||||
* @param num2 the second number in Fq12
|
||||
*
|
||||
* @return ret, a number in Fq12.
|
||||
*
|
||||
*/
|
||||
q12 Q12MinusMod(q12 num1, q12 num2)
|
||||
{
|
||||
q12 ret;
|
||||
|
||||
ret.high = Q4Minus(num1.high, num2.high);
|
||||
ret.mid = Q4Minus(num1.mid, num2.mid);
|
||||
ret.low = Q4Minus(num1.low, num2.low);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return (num1 + num2)
|
||||
*
|
||||
* @param num1 the first number in Fq12
|
||||
* @param num2 the second number in Fq12
|
||||
*
|
||||
* @return ret, a number in Fq12
|
||||
*
|
||||
*/
|
||||
q12 Q12AddMod(q12 num1, q12 num2)
|
||||
{
|
||||
q12 ret;
|
||||
|
||||
ret.high = Q4Add(num1.high, num2.high);
|
||||
ret.mid = Q4Add(num1.mid, num2.mid);
|
||||
ret.low = Q4Add(num1.low, num2.low);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief return num^(-1)
|
||||
*
|
||||
* @param num number in Fq12
|
||||
*
|
||||
* @return ret, number in Fq12
|
||||
*
|
||||
*/
|
||||
q12 Q12Reverse(q12 num)
|
||||
{
|
||||
q12 ret;
|
||||
q4 temp1, temp2;
|
||||
|
||||
ret.low = Q4Mult(num.low, num.low);
|
||||
ret.mid = Q4Mult(num.mid, num.high);
|
||||
ret.mid = Q4Txx(ret.mid);
|
||||
ret.low = Q4Minus(ret.low, ret.mid);
|
||||
|
||||
ret.high = Q4Mult(num.high, num.high);
|
||||
ret.high = Q4Txx(ret.high);
|
||||
ret.mid = Q4Mult(num.low, num.mid);
|
||||
ret.mid = Q4Minus(ret.high, ret.mid);
|
||||
|
||||
ret.high = Q4Mult(num.mid, num.mid);
|
||||
temp1 = Q4Mult(num.low, num.high);
|
||||
ret.high = Q4Minus(ret.high, temp1);
|
||||
|
||||
temp1 = Q4Mult(num.mid, ret.high);
|
||||
temp1 = Q4Txx(temp1);
|
||||
|
||||
temp2 = Q4Mult(num.low, ret.low);
|
||||
temp1 = Q4Add(temp1, temp2);
|
||||
|
||||
temp2 = Q4Mult(num.high, ret.mid);
|
||||
temp2 = Q4Txx(temp2);
|
||||
temp1 = Q4Add(temp1, temp2);
|
||||
|
||||
temp1 = Q4Reverse(temp1);
|
||||
|
||||
ret.low = Q4Mult(ret.low, temp1);
|
||||
ret.mid = Q4Mult(ret.mid, temp1);
|
||||
ret.high = Q4Mult(ret.high, temp1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief compute g^r. scan every bit of r
|
||||
*
|
||||
* @param g a number in Fq12
|
||||
* @param r power, a big number, r >= 0
|
||||
*
|
||||
* @return ret, a number in Fq12
|
||||
*
|
||||
*/
|
||||
q12 Q12PowerMod(q12 g, big8w r)
|
||||
{
|
||||
bool flag;
|
||||
int bitindex = Big8wHighestbit(&r);
|
||||
int i = BIGNUMBER_SIZE_8WORD - 1;
|
||||
uint32_t elem;
|
||||
q12 ret = g, temp = g;
|
||||
q12 one;
|
||||
|
||||
memset(&one, 0x00, BIG8W_BYTESIZE * 12);
|
||||
one.low.low.low.word[0] = 1;
|
||||
|
||||
while (i && r.word[i] == 0)
|
||||
i--;
|
||||
if (i < 0)
|
||||
return one;
|
||||
elem = r.word[i];
|
||||
|
||||
bitindex--;
|
||||
while (bitindex >= 0) {
|
||||
flag = (elem >> (bitindex--)) & 1;
|
||||
ret = Q12MultMod(temp, temp);
|
||||
if (flag)
|
||||
ret = Q12MultMod(ret, g);
|
||||
temp = ret;
|
||||
}
|
||||
|
||||
i--;
|
||||
for (; i >= 0; i--) {
|
||||
elem = r.word[i];
|
||||
bitindex = 31;
|
||||
while (bitindex >= 0) {
|
||||
flag = (elem >> (bitindex--)) & 1;
|
||||
ret = Q12MultMod(temp, temp);
|
||||
if (flag)
|
||||
ret = Q12MultMod(ret, g);
|
||||
temp = ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief compute f^(curve.q^(flag)); f = (f11, f10, ... f0), f^(curve.q^(flag)) = (f11*c11, f10*c10, ... f0*c0)
|
||||
*
|
||||
* @param f pointer of a number in Fq12
|
||||
* @param flag 1, 2, 6;
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void Q12Frobenius(q12* f, uint8_t flag)
|
||||
{
|
||||
if (flag == 1) {
|
||||
f->high.high.high = Big8wMultMod(f->high.high.high, frobenius_constant_1[11], curve.q);
|
||||
f->high.high.low = Big8wMultMod(f->high.high.low, frobenius_constant_1[10], curve.q);
|
||||
f->high.low.high = Big8wMultMod(f->high.low.high, frobenius_constant_1[9], curve.q);
|
||||
f->high.low.low = Big8wMultMod(f->high.low.low, frobenius_constant_1[8], curve.q);
|
||||
|
||||
f->mid.high.high = Big8wMultMod(f->mid.high.high, frobenius_constant_1[7], curve.q);
|
||||
f->mid.high.low = Big8wMultMod(f->mid.high.low, frobenius_constant_1[6], curve.q);
|
||||
f->mid.low.high = Big8wMultMod(f->mid.low.high, frobenius_constant_1[5], curve.q);
|
||||
f->mid.low.low = Big8wMultMod(f->mid.low.low, frobenius_constant_1[4], curve.q);
|
||||
|
||||
f->low.high.high = Big8wMultMod(f->low.high.high, frobenius_constant_1[3], curve.q);
|
||||
f->low.high.low = Big8wMultMod(f->low.high.low, frobenius_constant_1[2], curve.q);
|
||||
f->low.low.high = Big8wMultMod(f->low.low.high, frobenius_constant_1[1], curve.q);
|
||||
f->low.low.low = Big8wMultMod(f->low.low.low, frobenius_constant_1[0], curve.q);
|
||||
}
|
||||
|
||||
else if (flag == 2) {
|
||||
|
||||
f->high.high.high = Big8wMultMod(f->high.high.high, frobenius_constant_2[11], curve.q);
|
||||
f->high.high.low = Big8wMultMod(f->high.high.low, frobenius_constant_2[10], curve.q);
|
||||
f->high.low.high = Big8wMultMod(f->high.low.high, frobenius_constant_2[9], curve.q);
|
||||
f->high.low.low = Big8wMultMod(f->high.low.low, frobenius_constant_2[8], curve.q);
|
||||
|
||||
f->mid.high.high = Big8wMultMod(f->mid.high.high, frobenius_constant_2[7], curve.q);
|
||||
f->mid.high.low = Big8wMultMod(f->mid.high.low, frobenius_constant_2[6], curve.q);
|
||||
f->mid.low.high = Big8wMultMod(f->mid.low.high, frobenius_constant_2[5], curve.q);
|
||||
f->mid.low.low = Big8wMultMod(f->mid.low.low, frobenius_constant_2[4], curve.q);
|
||||
|
||||
f->low.high.high = Big8wMultMod(f->low.high.high, frobenius_constant_2[3], curve.q);
|
||||
f->low.high.low = Big8wMultMod(f->low.high.low, frobenius_constant_2[2], curve.q);
|
||||
f->low.low.high = Big8wMultMod(f->low.low.high, frobenius_constant_2[1], curve.q);
|
||||
f->low.low.low = Big8wMultMod(f->low.low.low, frobenius_constant_2[0], curve.q);
|
||||
|
||||
}
|
||||
|
||||
else if (flag == 6) {
|
||||
f->high.high.high = Big8wMinusMod(curve.q, f->high.high.high, curve.q);
|
||||
f->high.high.low = Big8wMinusMod(curve.q, f->high.high.low, curve.q);
|
||||
|
||||
f->mid.low.high = Big8wMinusMod(curve.q, f->mid.low.high, curve.q);
|
||||
f->mid.low.low = Big8wMinusMod(curve.q, f->mid.low.low, curve.q);
|
||||
|
||||
f->low.high.high = Big8wMinusMod(curve.q, f->low.high.high, curve.q);
|
||||
f->low.high.low = Big8wMinusMod(curve.q, f->low.high.low, curve.q);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief compute Frobenius(Q)
|
||||
* Q = Q(x, y), point in group G2;first convert x, y to q12 number:(x*beta^(-1/2), y*beta(-1/3))
|
||||
* then run Q12Frobenius, last convert back to G2point(ret.x*(beta^(1/2)), ret.y*(beta^(1/3)))
|
||||
*
|
||||
* @param Q point in group G2
|
||||
* @param Q1 pointer of a point in group G2, store the result
|
||||
* @param flag power of frobenius
|
||||
*
|
||||
* @result Q1
|
||||
*
|
||||
*/
|
||||
void G2pointFrobenius(G2point Q, G2point* Q1, uint8_t flag)
|
||||
{
|
||||
q12 temp, ret;
|
||||
|
||||
Q12Zero(&temp);
|
||||
Q12Zero(&ret);
|
||||
|
||||
ret.low.low = Q.x;
|
||||
temp.mid.high.high = qnr;
|
||||
ret = Q12MultMod(ret, temp);
|
||||
Q12Frobenius(&ret, flag);
|
||||
memset(temp.mid.high.high.word, 0x00, BIG8W_BYTESIZE);
|
||||
temp.high.low.low.word[0] = 1;
|
||||
ret = Q12MultMod(ret, temp);
|
||||
Q1->x = ret.low.low;
|
||||
|
||||
Q12Zero(&ret);
|
||||
Q12Zero(&temp);
|
||||
|
||||
ret.low.low = Q.y;
|
||||
temp.low.high.high = qnr;
|
||||
ret = Q12MultMod(ret, temp);
|
||||
Q12Frobenius(&ret, flag);
|
||||
memset(temp.low.high.high.word, 0x00, BIG8W_BYTESIZE);
|
||||
temp.low.high.low.word[0] = 1;
|
||||
ret = Q12MultMod(ret, temp);
|
||||
Q1->y = ret.low.low;
|
||||
}
|
||||
/**
|
||||
* @brief line function defined in SM9 and a Q12MultMod
|
||||
*
|
||||
* @param P a point in group G1
|
||||
* @param T a pointer of a point in group G2
|
||||
* @param Q a point in group G2
|
||||
* @param doubleflag if (*T) == Q
|
||||
* @param f a pointer of a number in Fq12, (*f) = (*f) * g(T, Q, P), g(T, Q, P) is the line function defined in SM9
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
void Line(G1point P, G2point* T, G2point Q, bool doubleflag, q12* f)
|
||||
{
|
||||
q2 lambda, temp;
|
||||
q12 ret;
|
||||
|
||||
Q12Zero(&ret);
|
||||
Q2Zero(&temp);
|
||||
|
||||
if (doubleflag) {
|
||||
|
||||
if (Q2Equal(&Q.x, &temp) && Q2Equal(&Q.y, &temp)) // Q = T = O
|
||||
return;
|
||||
|
||||
lambda = Q2Mult(Q.x, Q.x);
|
||||
lambda = Q2Add(lambda, Q2Add(lambda, lambda));
|
||||
lambda = Q2Mult(
|
||||
lambda,
|
||||
Q2Reverse(Q2Add(Q.y, Q.y)));
|
||||
}
|
||||
else {
|
||||
if (Q2Equal(&T->x, &Q.x)){
|
||||
// T = -Q => T = T + Q = O
|
||||
Q2Zero(&T->x), Q2Zero(&T->y);
|
||||
// g(T, Q, P) = xP - xQ
|
||||
temp.high = qnr;
|
||||
temp = Q2Mult(temp, Q.x);
|
||||
temp = Q2Negate(temp);
|
||||
ret.mid.high = temp;
|
||||
ret.low.low.low = P.x;
|
||||
|
||||
*f = Q12MultMod(*f, ret);
|
||||
}
|
||||
else if (Q2Equal(&T->x, &temp) && Q2Equal(&T->y, &temp)){ // T = O
|
||||
// g(U, V, O) = 1 => f * g(U, V, O) = f; *T = T + Q = Q
|
||||
*T = Q;
|
||||
return;
|
||||
}
|
||||
else if (Q2Equal(&Q.x, &temp) && Q2Equal(&Q.y, &temp)){ // Q = O
|
||||
// g(U, V, O) = 1 => f * g(U, V, O) = f; *T = T + Q = T
|
||||
return;
|
||||
}
|
||||
|
||||
lambda = Q2Mult(
|
||||
Q2Minus(T->y, Q.y),
|
||||
Q2Reverse(Q2Minus(T->x, Q.x)));
|
||||
}
|
||||
|
||||
temp.high = qnr;
|
||||
|
||||
ret.high.high = lambda;
|
||||
ret.high.high.high = Big8wMultMod(ret.high.high.high, P.x, curve.q);
|
||||
ret.high.high.low = Big8wMultMod(ret.high.high.low, P.x, curve.q);
|
||||
ret.high.high = Q2Mult(ret.high.high, temp);
|
||||
|
||||
ret.low.high = Q2Minus(
|
||||
T->y,
|
||||
Q2Mult(lambda, T->x));
|
||||
ret.low.high = Q2Mult(temp, ret.low.high);
|
||||
|
||||
ret.low.low.low = Big8wMinusMod(curve.q, P.y, curve.q);
|
||||
|
||||
*T = G2PointAdd(Q, *T);
|
||||
*f = Q12MultMod(ret, *f);
|
||||
}
|
||||
/**
|
||||
* @brief compute (f^(curve.q^(12) - 1)), called by BiLinearParing function(in topfunc.h).
|
||||
*
|
||||
* @param f a pointer of a number in Fq12
|
||||
*
|
||||
* @return null, result stored in *f.
|
||||
*
|
||||
*/
|
||||
// t = 0x60000000 0058F98A
|
||||
void LastPower(q12* f)
|
||||
{
|
||||
q12 m, g, s, temp;
|
||||
|
||||
m = Q12Reverse(*f);
|
||||
Q12Frobenius(f, 6);
|
||||
// f = f^(q^6 - 1)
|
||||
*f = Q12MultMod(*f, m);
|
||||
m = *f;
|
||||
Q12Frobenius(f, 2);
|
||||
*f = Q12MultMod(*f, m); // f = f^(q^6 - 1)(q^2+1)
|
||||
s = *f;
|
||||
|
||||
// hard part
|
||||
s = *f;
|
||||
m = s, temp = m;
|
||||
Q12Frobenius(&temp, 1);
|
||||
s = temp;
|
||||
Q12Frobenius(&temp, 1);
|
||||
s = Q12MultMod(s, temp);
|
||||
Q12Frobenius(&temp, 1);
|
||||
s = Q12MultMod(s, temp);
|
||||
|
||||
temp = Q12PowerMod(m, t);
|
||||
temp = Q12PowerMod(temp, t);
|
||||
|
||||
g = Q12MultMod(temp, temp);
|
||||
temp = Q12MultMod(g, g);
|
||||
temp = Q12MultMod(temp, g);
|
||||
Q12Frobenius(&temp, 2);
|
||||
|
||||
s = Q12MultMod(s, temp);
|
||||
|
||||
temp = m;
|
||||
Q12Frobenius(&temp, 6);
|
||||
temp = Q12MultMod(temp, temp);
|
||||
s = Q12MultMod(s, temp);
|
||||
g = temp;
|
||||
|
||||
temp = Q12MultMod(g, g);
|
||||
g = Q12MultMod(temp, g);
|
||||
g = Q12PowerMod(g, t);
|
||||
|
||||
temp = Q12MultMod(g, g);
|
||||
s = Q12MultMod(s, Q12MultMod(temp, g));
|
||||
Q12Frobenius(&temp, 1);
|
||||
s = Q12MultMod(s, temp);
|
||||
|
||||
g = Q12PowerMod(g, t);
|
||||
temp = Q12MultMod(g, g);
|
||||
m = Q12MultMod(g, temp);
|
||||
s = Q12MultMod(s, m);
|
||||
s = Q12MultMod(s, temp);
|
||||
g = m;
|
||||
Q12Frobenius(&m, 1);
|
||||
s = Q12MultMod(s, m);
|
||||
|
||||
g = Q12MultMod(g, g);
|
||||
g = Q12PowerMod(g, t);
|
||||
|
||||
s = Q12MultMod(s, g);
|
||||
Q12Frobenius(&g, 1);
|
||||
s = Q12MultMod(s, g);
|
||||
|
||||
*f = s;;
|
||||
}
|
|
@ -0,0 +1,646 @@
|
|||
/*
|
||||
* 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 sm9.c
|
||||
* @brief API of SM9
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
#include <sm9.h>
|
||||
|
||||
#define SM4OUT 16 // 128 / 8
|
||||
|
||||
/**
|
||||
* @brief initialization function, to set value of SM9 curve elements and other essential parameters.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @result null
|
||||
*
|
||||
*/
|
||||
|
||||
void SM9Init()
|
||||
{
|
||||
big8w one;
|
||||
memset(one.word, 0x00, BIG8W_BYTESIZE);
|
||||
one.word[0] = 1;
|
||||
memset(curve.b.word, 0x00, BIG8W_BYTESIZE);
|
||||
curve.b.word[0] = 0x05;
|
||||
memcpy(curve.q.word, sm9_q, BIG8W_BYTESIZE);
|
||||
memcpy(curve.N.word, sm9_N, BIG8W_BYTESIZE);
|
||||
memcpy(P1.x.word, sm9_P1_x, BIG8W_BYTESIZE);
|
||||
memcpy(P1.y.word, sm9_P1_y, BIG8W_BYTESIZE);
|
||||
memcpy(P2.x.high.word, sm9_P2_x_high, BIG8W_BYTESIZE);
|
||||
memcpy(P2.x.low.word, sm9_P2_x_low, BIG8W_BYTESIZE);
|
||||
memcpy(P2.y.high.word, sm9_P2_y_high, BIG8W_BYTESIZE);
|
||||
memcpy(P2.y.low.word, sm9_P2_y_low, BIG8W_BYTESIZE);
|
||||
memset(t.word, 0x00, BIG8W_BYTESIZE);
|
||||
t.word[0] = 0x0058F98A, t.word[1] = 0x60000000;
|
||||
frobenius_constant_1[0] = one;
|
||||
memcpy(frobenius_constant_1[1].word, fc1_1, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[2].word, fc1_2, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[3].word, fc1_3, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[4].word, fc1_4, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[5].word, fc1_5, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[6].word, fc1_6, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[7].word, fc1_7, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[8].word, fc1_8, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[9].word, fc1_9, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[10].word, fc1_10, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_1[11].word, fc1_11, BIG8W_BYTESIZE);
|
||||
frobenius_constant_2[0] = one;
|
||||
frobenius_constant_2[1] = one;
|
||||
memcpy(frobenius_constant_2[2].word, fc2_2, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[3].word, fc2_3, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[4].word, fc2_4, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[5].word, fc2_5, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[6].word, fc2_6, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[7].word, fc2_7, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[8].word, fc2_8, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[9].word, fc2_9, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[10].word, fc2_10, BIG8W_BYTESIZE);
|
||||
memcpy(frobenius_constant_2[11].word, fc2_11, BIG8W_BYTESIZE);
|
||||
memcpy(qnr.word, sm9_qnr, BIG8W_BYTESIZE);
|
||||
memcpy(q_2k.word, sm9_q_2k, BIG8W_BYTESIZE);
|
||||
memcpy(N_2k.word, sm9_N_2k, BIG8W_BYTESIZE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief sign algorithm of SM9
|
||||
*
|
||||
* @param message data need to sign with sign_secretkey
|
||||
* @param msgbytelen length of message, byte size
|
||||
* @param ds sign_secretkey
|
||||
* @param Ppub_s sign_publickey
|
||||
*
|
||||
* @return Signature
|
||||
*
|
||||
*/
|
||||
Signature SM9Sign(unsigned char *message, uint32_t msgbytelen, G1point ds, G2point Ppub_s)
|
||||
{
|
||||
uint8_t *msg_w;
|
||||
big8w r, L_temp, zero;
|
||||
q12 g, w;
|
||||
Signature sig;
|
||||
|
||||
msg_w = (uint8_t *)(malloc(msgbytelen + BIG8W_BYTESIZE * 12));
|
||||
|
||||
memset(zero.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
g = BiLinearPairing(P1, Ppub_s); //e(P1, Ppub_s)
|
||||
|
||||
do
|
||||
{
|
||||
r = RandomNumGenerate();
|
||||
|
||||
w = Q12PowerMod(g, r); // w = g^r
|
||||
|
||||
JoinMsgW(message, msgbytelen, &w, msg_w);
|
||||
sig.h = H(msg_w, msgbytelen + BIG8W_BYTESIZE * 12, 0x02);
|
||||
|
||||
L_temp = Big8wMinusMod(r, sig.h, curve.N);
|
||||
} while (Big8wEqual(&L_temp, &zero));
|
||||
|
||||
sig.S = G1pointMult(L_temp, ds);
|
||||
|
||||
free(msg_w);
|
||||
|
||||
return sig;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief signature verify algorithm of SM9
|
||||
*
|
||||
* @param ID id of user who generate the signature
|
||||
* @param IDlen length of ID
|
||||
* @param hid function id defined in SM9
|
||||
* @param message message that received from counterpart
|
||||
* @param msgbytelen length of message, byte size
|
||||
* @param signature signature received from counterpart
|
||||
* @param Ppub_s sign_publickey
|
||||
*
|
||||
* @return true if signature verified successfully, else false
|
||||
*
|
||||
*/
|
||||
bool SM9VerifySignature(
|
||||
unsigned char* ID, unsigned char IDlen, unsigned char hid,
|
||||
unsigned char* message, unsigned int msgbytelen,
|
||||
Signature signature, G2point Ppub_s)
|
||||
{
|
||||
unsigned char *msg_w;
|
||||
big8w zero, h;
|
||||
G2point P;
|
||||
q12 g, t, w;
|
||||
|
||||
msg_w = (unsigned char *)(malloc(msgbytelen + BIG8W_BYTESIZE * 12));
|
||||
memset(zero.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
if (Big8wBigThan(&signature.h, &curve.N)
|
||||
|| Big8wEqual(&signature.h, &zero))
|
||||
return false;
|
||||
|
||||
if (!PointInG1(signature.S))
|
||||
return false;
|
||||
|
||||
g = BiLinearPairing(P1, Ppub_s);
|
||||
|
||||
t = Q12PowerMod(g, signature.h);
|
||||
|
||||
unsigned char* id_hid;
|
||||
id_hid = (unsigned char*)malloc((IDlen + 1));
|
||||
JoinIDhid(ID, IDlen, hid, id_hid);
|
||||
|
||||
h = H(id_hid, IDlen + 1, 0x01);
|
||||
|
||||
P = G2PointMult(h, P2);
|
||||
|
||||
P = G2PointAdd(P, Ppub_s);
|
||||
|
||||
g = BiLinearPairing(signature.S, P);
|
||||
|
||||
w = Q12MultMod(g, t);
|
||||
|
||||
JoinMsgW(message, msgbytelen, &w, msg_w);
|
||||
h = H(msg_w, msgbytelen + BIG8W_BYTESIZE * 12, 0x02);
|
||||
|
||||
free(id_hid);
|
||||
free(msg_w);
|
||||
|
||||
return Big8wEqual(&h, &signature.h);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief the first step of key exchange of SM9, produce R(the data send to the counterpart)
|
||||
*
|
||||
* @param ID ID of counterpart
|
||||
* @param IDlen length of ID
|
||||
* @param r a pointer of a big number, random big number
|
||||
* @param R a pointer of a point in group G1, store the result
|
||||
* @param encrypt_publickey encrypt_publickey
|
||||
*
|
||||
* @result R
|
||||
*
|
||||
*/
|
||||
void SM9KeyExchangeProduceR(unsigned char* ID, unsigned char IDlen, big8w* r, G1point* R, G1point encrypt_publickey)
|
||||
{
|
||||
unsigned char hid = 0x02;
|
||||
unsigned char *id_hid;
|
||||
|
||||
id_hid = (unsigned char *)(malloc(IDlen + 1));
|
||||
|
||||
JoinIDhid(ID, IDlen, hid, id_hid);
|
||||
|
||||
*R = G1pointMult(H(id_hid, IDlen + 1, 0x01), P1);
|
||||
*R = G1pointAdd(*R, encrypt_publickey);
|
||||
*r = RandomNumGenerate();
|
||||
*R = G1pointMult(*r, *R);
|
||||
|
||||
free(id_hid);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief the second step of key exchange of SM9, produce key
|
||||
*
|
||||
* @param RA a pointer of a point in group G1, produced in function SM9KeyExchangeProduceR
|
||||
* @param RB a pointer of a point in group G1, received from counterpart
|
||||
* @param r a pointer of a big number, random big number, produced in function SM9KeyExchangeProduceR.
|
||||
* @param klen_bitsize length of key to be generated, bit size!!!
|
||||
* @param challengerID ID of the challenger of key exchange
|
||||
* @param challengerIDlen length of chalengerID
|
||||
* @param responserID ID of the responser of key exchange
|
||||
* @param responserIDlen length of responserID
|
||||
* @param resultkey unsigned char string, store the key generated in key exchange
|
||||
* @param encrypt_publickey encrypt public key
|
||||
* @param encrypt_secretkey encrypt secret key
|
||||
*
|
||||
* @result resultkey
|
||||
*
|
||||
*/
|
||||
bool SM9KeyExchangeProduceKey(G1point* RA, G1point* RB, big8w* r, uint32_t klen_bitsize,
|
||||
unsigned char* challengerID, unsigned char challengerIDlen,
|
||||
unsigned char* responserID, unsigned char responserIDlen,
|
||||
q12 *g1, q12* g2, q12* g3, char* resultkey, bool sponsor,
|
||||
G1point encrypt_publickey, G2point encrypt_secretkey)
|
||||
{
|
||||
|
||||
unsigned char *string;
|
||||
int i, stringlen;
|
||||
|
||||
stringlen = challengerIDlen + responserIDlen + BIG8W_BYTESIZE * (2 * 2 + 12 * 3);
|
||||
string = (uint8_t *)(malloc(stringlen));
|
||||
|
||||
if (!PointInG1(*RB)){
|
||||
printf("Point error, point is not in G1\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
*g1 = BiLinearPairing(encrypt_publickey, P2);
|
||||
*g1 = Q12PowerMod(*g1, *r);
|
||||
|
||||
*g2 = BiLinearPairing(*RB, encrypt_secretkey);
|
||||
|
||||
if (!sponsor){ // notice that the format of challenger and responser is similar.
|
||||
*g3 = *g1;
|
||||
*g1 = *g2;
|
||||
*g2 = *g3;
|
||||
}
|
||||
|
||||
*g3 = Q12PowerMod(*g2, *r);
|
||||
|
||||
JoinIDAIDBRARBg123(challengerID, challengerIDlen, responserID, responserIDlen, RA, RB, g1, g2, g3, string);
|
||||
|
||||
KDF(string, stringlen, klen_bitsize, (uint8_t*)resultkey);
|
||||
|
||||
free(string);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief the third step of SM9 key exchange, to verify the key is right.
|
||||
*
|
||||
* @param g1 pointer of the first q12 number
|
||||
* @param g2 pointer of the second q12 number
|
||||
* @param g3 pointer of the second q12 number
|
||||
* @param RA pointer of a G1point of the challenger
|
||||
* @param RB pointer of a G1point of the responser
|
||||
* @param challengerID ID of the challenger of key exchange
|
||||
* @param challengerIDlen length of chalengerID
|
||||
* @param responserID ID of the responser of key exchange
|
||||
* @param responserIDlen length of responserID
|
||||
* @param S1 hash value, function flag = 0x82
|
||||
* @param SA hash value, function flag = 0x83
|
||||
*
|
||||
* @result two hash values: S1, SA
|
||||
*
|
||||
*/
|
||||
bool SM9KeyExchangeVerifyKey(q12* g1, q12 *g2, q12* g3, G1point* RA, G1point* RB,
|
||||
unsigned char* challengerID, unsigned char challengerIDlen,
|
||||
unsigned char* responserID, unsigned char responserIDlen,
|
||||
unsigned char *S1, unsigned char* SA)
|
||||
{
|
||||
HashTwice(challengerID, challengerIDlen, responserID, responserIDlen, RA, RB, g1, g2, g3, 0x82, S1);
|
||||
|
||||
HashTwice(challengerID, challengerIDlen, responserID, responserIDlen, RA, RB, g1, g2, g3, 0x83, SA);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief key encapsulation define in SM9, called by encrypt of SM9.
|
||||
*
|
||||
* @param ID counterpart's ID
|
||||
* @param IDlen length of ID
|
||||
* @param hid function flag defined in SM9,
|
||||
* @param Ppub_e encrypt_publickey
|
||||
* @param klen_bitsize length of key to be generated by KDF(), bit size!!!
|
||||
* @param K key generated by KDF()
|
||||
* @param C packaged K
|
||||
*
|
||||
* @result K, C
|
||||
*
|
||||
*/
|
||||
void SM9KeyPackage(unsigned char* ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e, uint32_t klen_bitsize, unsigned char* K, G1point* C)
|
||||
{
|
||||
unsigned char *c_w_id, * id_hid;
|
||||
big8w r;
|
||||
G1point temp, QB;
|
||||
q12 g;
|
||||
|
||||
c_w_id = (unsigned char*)(malloc(BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + IDlen));
|
||||
id_hid = (unsigned char*)(malloc(IDlen + 1));
|
||||
|
||||
JoinIDhid(ID, IDlen, hid, id_hid);
|
||||
|
||||
QB = G1pointMult(
|
||||
H(id_hid, IDlen + 1, 0x01),
|
||||
P1);
|
||||
QB = G1pointAdd(QB, Ppub_e);
|
||||
|
||||
do {
|
||||
r = RandomNumGenerate();
|
||||
|
||||
temp = G1pointMult(r,QB);
|
||||
|
||||
g = BiLinearPairing(Ppub_e, P2);
|
||||
|
||||
g = Q12PowerMod(g, r);
|
||||
|
||||
JoinCwID(&temp, &g, ID, IDlen, c_w_id);
|
||||
|
||||
KDF(c_w_id, BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + IDlen, klen_bitsize, K);
|
||||
|
||||
} while (StringEqualZero(K, klen_bitsize));
|
||||
|
||||
free(c_w_id);
|
||||
free(id_hid);
|
||||
|
||||
*C = temp;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief key depackage of SM9
|
||||
*
|
||||
* @param C a point in group G1, received from the counterpart
|
||||
* @param de encrypt_secretkey
|
||||
* @param ID ID of self
|
||||
* @param IDlen length of ID
|
||||
* @param klen_bitsize length of key to be generated, bit size!!!
|
||||
* @param K key generated
|
||||
*
|
||||
* @result K
|
||||
*
|
||||
*/
|
||||
bool SM9KeyDepackage(G1point C, G2point de, unsigned char* ID, unsigned char IDlen, unsigned int klen_bitsize, unsigned char* K)
|
||||
{
|
||||
unsigned char* c_w_id;
|
||||
q12 w;
|
||||
|
||||
c_w_id = (unsigned char*)(malloc(BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + IDlen));
|
||||
|
||||
if (!PointInG1(C)){
|
||||
printf("point not in G1\n");
|
||||
free(c_w_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
w = BiLinearPairing(C, de);
|
||||
|
||||
JoinCwID(&C, &w, ID, IDlen, c_w_id);
|
||||
|
||||
|
||||
KDF(c_w_id, BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + IDlen, klen_bitsize, K);
|
||||
|
||||
free(c_w_id);
|
||||
|
||||
if (StringEqualZero(K, klen_bitsize))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Encrypt of SM9 with KDF
|
||||
*
|
||||
* @param message data to be encrypted
|
||||
* @param msglen_bitsieze length of message, bit size!!!
|
||||
* @param K2_len_bitsize K2_len, defined in SM9
|
||||
* @param ID ID of counterpart
|
||||
* @param IDlen length of ID
|
||||
* @param hid function flag defined in SM9
|
||||
* @param Ppub_e encrypt_publickey
|
||||
* @param C ciphertext of message
|
||||
*
|
||||
* @result C
|
||||
*
|
||||
*/
|
||||
bool SM9EncryptWithKDF(unsigned char* message, unsigned int msglen_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char* ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e, unsigned char *C)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int klen_bitsize = msglen_bitsize + K2_len_bitsize;
|
||||
unsigned char *K, *C2, *C3, *C2K2;
|
||||
G1point C1;
|
||||
|
||||
K = (uint8_t *)(malloc( ((klen_bitsize >> 8) + 1) * (SM3OUT_32BYTES)) );
|
||||
C2 = (uint8_t *)(malloc(msglen_bitsize >> 3)); // msglen_bitsize / 8
|
||||
C3 = (uint8_t *)(malloc(BIG8W_BYTESIZE));
|
||||
C2K2 = (uint8_t *)(malloc((msglen_bitsize >> 3) + (K2_len_bitsize >> 3))); // msglen_bitsize / 8 + K2_len_bitsize / 8
|
||||
|
||||
do{
|
||||
SM9KeyPackage(ID, IDlen, hid, Ppub_e, klen_bitsize, K, &C1);
|
||||
} while (StringEqualZero(K, msglen_bitsize >> 3));
|
||||
|
||||
XOR(message, msglen_bitsize >> 3, K, C2);
|
||||
|
||||
for (i = 0; i < msglen_bitsize >> 3 ; i++)
|
||||
C2K2[i] = C2[i];
|
||||
for (i; i < (klen_bitsize >> 3); i++)
|
||||
C2K2[i] = K[i];
|
||||
|
||||
sm3(C2K2, (msglen_bitsize >> 3) + (K2_len_bitsize >> 3), C3);
|
||||
|
||||
// C = C1||C3||C2
|
||||
i = 0;
|
||||
Big8wIntou8string(&C1.x, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
Big8wIntou8string(&C1.y, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
for (i = BIG8W_BYTESIZE * 2; i < BIG8W_BYTESIZE * 2 + (SM3OUT_32BYTES); i++)
|
||||
C[i] = C3[i - BIG8W_BYTESIZE * 2];
|
||||
|
||||
for (; i < BIG8W_BYTESIZE * 2 + (SM3OUT_32BYTES) + (msglen_bitsize >> 3); i++)
|
||||
C[i] = C2[i - (BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES)];
|
||||
|
||||
free(C2);
|
||||
free(C3);
|
||||
free(C2K2);
|
||||
free(K);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Decrypt function of SM9 with KDF
|
||||
*
|
||||
* @param ID ID of self
|
||||
* @param IDlen length of ID
|
||||
* @param message decrypted date
|
||||
* @param msglen_bitsize length of message, bit size!!!
|
||||
* @param K2_len_bitsize K2_len defined in SM9
|
||||
* @param C ciphertext, received from counterpart
|
||||
* @param encrypt_secretkey encrypt_secretkey of self
|
||||
*
|
||||
* @result message
|
||||
*
|
||||
*/
|
||||
bool SM9DecryptWithKDF(unsigned char* ID, unsigned char IDlen,
|
||||
unsigned char* message, unsigned int msglen_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *C, G2point encrypt_secretkey)
|
||||
{
|
||||
G1point C1;
|
||||
|
||||
unsigned char *K;
|
||||
unsigned char *u;
|
||||
unsigned char *C2K2;
|
||||
unsigned int i;
|
||||
unsigned int klen_bitsize = msglen_bitsize + K2_len_bitsize;
|
||||
|
||||
K = (uint8_t *)(malloc( ((klen_bitsize >> 8) + 1) * (SM3OUT_32BYTES)) );
|
||||
u = (unsigned char *)(malloc(SM3OUT_32BYTES));
|
||||
C2K2 = (unsigned char *)(malloc((msglen_bitsize >> 3) + (K2_len_bitsize >> 3)));
|
||||
|
||||
U8stringToG1point(C, &C1);
|
||||
|
||||
SM9KeyDepackage(C1, encrypt_secretkey, ID, IDlen, msglen_bitsize + K2_len_bitsize, K);
|
||||
|
||||
if (StringEqualZero(K, msglen_bitsize >> 3)){
|
||||
free(K);
|
||||
free(u);
|
||||
free(C2K2);
|
||||
return false;
|
||||
}
|
||||
|
||||
XOR(K, msglen_bitsize >> 3, C + BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE, (unsigned char*)message);
|
||||
|
||||
for (i = 0; i < msglen_bitsize >> 3; i++)
|
||||
C2K2[i] = (C + BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE)[i];
|
||||
for (; i < (msglen_bitsize >> 3) + (K2_len_bitsize >> 3); i++)
|
||||
C2K2[i] = K[i];
|
||||
|
||||
sm3(C2K2, (msglen_bitsize >> 3) + (K2_len_bitsize >> 3), u);
|
||||
|
||||
free(K);
|
||||
free(C2K2);
|
||||
|
||||
for (i = 0; i < SM3OUT_32BYTES; i++)
|
||||
if (u[i] != (C + BIG8W_BYTESIZE * 2)[i])
|
||||
{
|
||||
printf("hash value error!\n");
|
||||
free(u);;
|
||||
return false;
|
||||
}
|
||||
|
||||
free(u);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Encrypt function of SM9 with SM4
|
||||
*
|
||||
* @param message data to be encrypted
|
||||
* @param msglen_bitsize length of message, bit size !!!
|
||||
* @param K1_len_bitsize K1_len defined in SM9, length of the key of SM4
|
||||
* @param K2_len_bitsize K2_len defined in SM9
|
||||
* @param ID ID of counterpart
|
||||
* @param IDlen length of ID
|
||||
* @param hid function flag defined in SM9
|
||||
* @param Ppub_e encrypt_publickey
|
||||
* @param C ciphertext of message
|
||||
*
|
||||
* @result C
|
||||
*
|
||||
*/
|
||||
bool SM9EncryptWithSM4(unsigned char* message, unsigned int msglen_bitsize,
|
||||
unsigned int K1_len_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char* ID, unsigned char IDlen, unsigned char hid, G1point Ppub_e,
|
||||
unsigned char *C)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int klen_bitsize = K1_len_bitsize + K2_len_bitsize;
|
||||
unsigned int C2byteslen = ((K1_len_bitsize >> 7) + 1) * (SM4OUT);
|
||||
unsigned char *K, *C2, *C3, *C2K2;
|
||||
G1point C1;
|
||||
|
||||
K = (uint8_t *)(malloc(((klen_bitsize >> 8) + 1) * SM3OUT_32BYTES));
|
||||
C2 = (uint8_t *)(malloc(C2byteslen));
|
||||
C3 = (uint8_t *)(malloc(256 / 8));
|
||||
C2K2 = (uint8_t *)(malloc(C2byteslen + (K2_len_bitsize >> 3)));
|
||||
|
||||
do{
|
||||
SM9KeyPackage(ID, IDlen, hid, Ppub_e, klen_bitsize, K, &C1);
|
||||
} while (StringEqualZero(K, K1_len_bitsize >> 3));
|
||||
|
||||
SM4EncryptWithEcbMode(message, (msglen_bitsize >> 3), K, C2);
|
||||
|
||||
for (i = 0; i < C2byteslen; i++) // join C2
|
||||
C2K2[i] = C2[i];
|
||||
for (; i < C2byteslen + (K2_len_bitsize >> 3); i++) // join K2
|
||||
C2K2[i] = K[i - C2byteslen + (K1_len_bitsize >> 3)];
|
||||
|
||||
sm3(C2K2, C2byteslen + (K2_len_bitsize >> 3), C3);
|
||||
|
||||
// C = C1||C3||C2
|
||||
i = 0;
|
||||
Big8wIntou8string(&C1.x, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
Big8wIntou8string(&C1.y, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
for (i = BIG8W_BYTESIZE * 2; i < BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES; i++)
|
||||
C[i] = C3[i - (BIG8W_BYTESIZE * 2)];
|
||||
|
||||
for (i = BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES; i < BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES + C2byteslen; i++)
|
||||
C[i] = C2[i - (BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES)];
|
||||
|
||||
free(C2);
|
||||
free(C3);
|
||||
free(C2K2);
|
||||
free(K);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Decrypt of SM9 with SM4
|
||||
*
|
||||
* @param ID ID of self
|
||||
* @param IDlen length of ID
|
||||
* @param message message to be decrypted, store the result
|
||||
* @param msglen length of message, byte size
|
||||
* @param K1_len_bitsize K1_len defined in SM9, bit size, length of key of SM4
|
||||
* @param K2_len_bitsize K2_len defined in SM9, bit size
|
||||
* @param C ciphertext received from counterpart
|
||||
* @param Cbyteslen length of C, byte size
|
||||
* @param encrypt_secretkey encrypt_secretkey of self
|
||||
*
|
||||
* @result message
|
||||
*
|
||||
*/
|
||||
bool SM9DecryptWithSM4(unsigned char* ID, unsigned char IDlen,
|
||||
unsigned char* message, unsigned int msglen, unsigned int K1_len_bitsize, unsigned int K2_len_bitsize,
|
||||
unsigned char *C, unsigned int Cbyteslen, G2point encrypt_secretkey)
|
||||
{
|
||||
G1point C1;
|
||||
unsigned int i;
|
||||
unsigned char *K;
|
||||
unsigned char *u;
|
||||
unsigned char *C2K2;
|
||||
unsigned int c_w_id_len;
|
||||
unsigned int C2byteslen = Cbyteslen - (BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES);
|
||||
unsigned int klen_bitsize = K1_len_bitsize + K2_len_bitsize;
|
||||
|
||||
K = (uint8_t *)(malloc(((klen_bitsize >> 8) + 1) * SM3OUT_32BYTES));
|
||||
u = (unsigned char *)(malloc(SM3OUT_32BYTES));
|
||||
C2K2 = (unsigned char *)(malloc(C2byteslen + (K2_len_bitsize >> 3)));
|
||||
|
||||
U8stringToG1point(C, &C1);
|
||||
|
||||
if (!SM9KeyDepackage(C1, encrypt_secretkey, ID, IDlen, (K1_len_bitsize + K2_len_bitsize), K))
|
||||
return false;
|
||||
|
||||
SM4DecryptWithEcbMode((C + BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES), C2byteslen, message, msglen, K);
|
||||
|
||||
for (i = 0; i < C2byteslen; i++)
|
||||
C2K2[i] = (C + BIG8W_BYTESIZE * 2 + SM3OUT_32BYTES)[i];
|
||||
for (i = C2byteslen; i < C2byteslen + (K2_len_bitsize >> 3); i++)
|
||||
C2K2[i] = K[i - C2byteslen + (K1_len_bitsize >> 3)];
|
||||
|
||||
sm3(C2K2, C2byteslen + (K2_len_bitsize >> 3), u);
|
||||
|
||||
free(K);
|
||||
free(C2K2);
|
||||
|
||||
for (i = 0; i < SM3OUT_32BYTES; i++)
|
||||
if (u[i] != (C + BIG8W_BYTESIZE * 2)[i]){
|
||||
printf("u != C3, decrypt failed\n");
|
||||
free(u);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(u);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* 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 sm9_para.c
|
||||
* @brief SM9 parameters
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ecc.h>
|
||||
#include <qn.h>
|
||||
|
||||
//extern char *device_id;
|
||||
//extern char *platform_id;
|
||||
|
||||
G1point P1;
|
||||
G2point P2;
|
||||
//G2point sign_publickey, encrypt_secretkey;
|
||||
//G1point sign_secretkey, encrypt_publickey;
|
||||
|
||||
|
||||
const uint32_t sm9_q[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xE351457D, 0xE56F9B27, 0x1A7AEEDB, 0x21F2934B,
|
||||
0xF58EC745, 0xD603AB4F, 0x02A3A6F1, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t sm9_N[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xD69ECF25, 0xE56EE19C, 0x18EA8BEE, 0x49F2934B,
|
||||
0xF58EC744, 0xD603AB4F, 0x02A3A6F1, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P1_x[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7C66DDDD, 0xE8C4E481, 0x09DC3280, 0xE1E40869,
|
||||
0x487D01D6, 0xF5ED0704, 0x62BF718F, 0x93DE051D,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P1_y[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x0A3EA616, 0x0C464CD7, 0xFA602435, 0x1C1C00CB,
|
||||
0x5C395BBC, 0x63106512, 0x4F21E607, 0x21FE8DDA,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P2_x_high[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xD8806141, 0x54806C11, 0x0F5E93C4, 0xF1DD2C19,
|
||||
0xB441A01F, 0x597B6027, 0x78640C98, 0x85AEF3D0,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P2_x_low[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948,
|
||||
0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P2_y_high[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x84EBEB96, 0x856DC76B, 0xA347C8BD, 0x0736A96F,
|
||||
0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09,
|
||||
};
|
||||
|
||||
const uint32_t sm9_P2_y_low[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xC999A7C7, 0x6215BBA5, 0xA71A0811, 0x47EFBA98,
|
||||
0x3D278FF2, 0x5F317015, 0x19BE3DA6, 0xA7CF28D5,
|
||||
};
|
||||
|
||||
const uint32_t fc1_1[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xE351457C, 0xE56F9B27, 0x1A7AEEDB, 0x21F2934B,
|
||||
0xF58EC745, 0xD603AB4F, 0x02A3A6F1, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc1_2[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xDA24D011, 0xF5B21FD3, 0x06DC5177, 0x9F9D4118,
|
||||
0xEE0BAF15, 0xF55ACC93, 0xDC0A3F2C, 0x6C648DE5,
|
||||
};
|
||||
|
||||
const uint32_t fc1_3[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x092c756c, 0xefbd7b54, 0x139e9d63, 0x82555233,
|
||||
0x0783182f, 0xe0a8debc, 0x269967c4, 0x49db721a,
|
||||
};
|
||||
|
||||
const uint32_t fc1_4[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e,
|
||||
0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58,
|
||||
};
|
||||
|
||||
const uint32_t fc1_5[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xabd5dbf2, 0x3c5217d3, 0x0c9de9ee, 0xda2ccadd,
|
||||
0x59865ffb, 0x51c73e55, 0x1d319b16, 0x771c15a7,
|
||||
};
|
||||
|
||||
const uint32_t fc1_6[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7be65333, 0xd5fc1196, 0x4f8b78f4, 0x78027235,
|
||||
0x02a3a6f2, 0xf3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc1_7[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676af24a, 0x0f738991, 0xcaef75e7, 0xa9f02115,
|
||||
0xf2eb2052, 0xe303ab4f, 0x02a3a6f0, 0xb6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc1_8[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235,
|
||||
0x02a3a6f2, 0xf3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc1_9[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676af249, 0x0f738991, 0xcaef75e7, 0xa9f02115,
|
||||
0xf2eb2052, 0xe303ab4f, 0x02a3a6f0, 0xb6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc1_10[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xa2a96686, 0x4c949c7f, 0xf8ff4c8a, 0x57d778a9,
|
||||
0x520347cc, 0x711e5f99, 0xf6983351, 0x2d40a38c,
|
||||
};
|
||||
|
||||
const uint32_t fc1_11[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x40a7def7, 0x98dafea8, 0x217ba251, 0xca1b1aa1,
|
||||
0xa38b7f78, 0x64e54bb6, 0x0c0b73a0, 0x88ff5c73,
|
||||
};
|
||||
|
||||
|
||||
const uint32_t fc2_2[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xE351457C, 0xE56F9B27, 0x1A7AEEDB, 0x21F2934B,
|
||||
0xF58EC745, 0xD603AB4F, 0x02A3A6F1, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc2_3[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xE351457C, 0xE56F9B27, 0x1A7AEEDB, 0x21F2934B,
|
||||
0xF58EC745, 0xD603AB4F, 0x02A3A6F1, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc2_4[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7BE65334, 0xD5FC1196, 0x4F8B78F4, 0x78027235,
|
||||
0x02A3A6F2, 0xF3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc2_5[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7BE65334, 0xD5FC1196, 0x4F8B78F4, 0x78027235,
|
||||
0x02A3A6F2, 0xF3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc2_6[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676AF249, 0x0F738991, 0xCAEF75E7, 0xA9F02115,
|
||||
0xF2EB2052, 0xE303AB4F, 0x02A3A6F0, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc2_7[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676AF249, 0x0F738991, 0xCAEF75E7, 0xA9F02115,
|
||||
0xF2EB2052, 0xE303AB4F, 0x02A3A6F0, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc2_8[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7BE65333, 0xD5FC1196, 0x4F8B78F4, 0x78027235,
|
||||
0x02A3A6F2, 0xF3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc2_9[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x7BE65333, 0xD5FC1196, 0x4F8B78F4, 0x78027235,
|
||||
0x02A3A6F2, 0xF3000000, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const uint32_t fc2_10[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676AF24A, 0x0F738991, 0xCAEF75E7, 0xA9F02115,
|
||||
0xF2EB2052, 0xE303AB4F, 0x02A3A6F0, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t fc2_11[BIGNUMBER_SIZE_8WORD] = {
|
||||
0x676AF24A, 0x0F738991, 0xCAEF75E7, 0xA9F02115,
|
||||
0xF2EB2052, 0xE303AB4F, 0x02A3A6F0, 0xB6400000,
|
||||
};
|
||||
|
||||
const uint32_t sm9_qnr[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xf1a8a2be, 0xf2b7cd93, 0x8d3d776d, 0x90f949a5,
|
||||
0xfac763a2, 0xeb01d5a7, 0x0151d378, 0x5b200000,
|
||||
};
|
||||
|
||||
const uint32_t sm9_q_2k[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xb417e2d2, 0x27dea312, 0xae1a5d3f, 0x88f8105f,
|
||||
0xd6706e7b, 0xe479b522, 0x56f62fbd, 0x2ea795a6,
|
||||
};
|
||||
|
||||
const uint32_t sm9_N_2k[BIGNUMBER_SIZE_8WORD] = {
|
||||
0xcd750c35, 0x7598cd79, 0xbb6daeab, 0xe4a08110,
|
||||
0x7d78a1f9, 0xbfee4bae, 0x63695d0e, 0x8894f5d1,
|
||||
};
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* 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 sm9_util.c
|
||||
* @brief the function called by SM9 function, including hash, KDF, produce random number, encrypt and decrypt algorithm, BiLinearPairing
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <sm9_util.h>
|
||||
#include <sm4.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief generate random bytes
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return uint8_t
|
||||
*
|
||||
*/
|
||||
uint8_t hw_get_random_byte(void)
|
||||
{
|
||||
static uint32_t lcg_state;
|
||||
static uint32_t nb_soft = 9876543;
|
||||
#define MAX_SOFT_RNG 1024
|
||||
static const uint32_t a = 1664525;
|
||||
static const uint32_t c = 1013904223;
|
||||
|
||||
nb_soft = (nb_soft + 1) % MAX_SOFT_RNG;
|
||||
lcg_state = (a * lcg_state + c);
|
||||
return (uint8_t) (lcg_state >> 24);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief generate random bytes stream
|
||||
*
|
||||
* @param buf buffer to store the random bytes
|
||||
* @param blen buffer length
|
||||
*
|
||||
* @return 1 if produce random bytes stream; 0 if buffer is null
|
||||
*/
|
||||
int crypto_rng_read(uint8_t *buf, size_t blen)
|
||||
{
|
||||
uint8_t *b = buf;
|
||||
size_t n;
|
||||
|
||||
if (!b)
|
||||
return -1;
|
||||
|
||||
for (n = 0; n < blen; n++)
|
||||
b[n] = hw_get_random_byte();
|
||||
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief generate random big number based on crypto_rng_read, bad prng version , only for test.
|
||||
* TODO: replace next version
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ret, big number r
|
||||
*
|
||||
*/
|
||||
big8w RandomNumGenerate()
|
||||
{
|
||||
char i = 0, j = 0;
|
||||
unsigned char random_byte[4];
|
||||
big8w ret;
|
||||
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE);
|
||||
|
||||
for (i = 0; i < BIGNUMBER_SIZE_8WORD; i++){
|
||||
for (j = 0; j < 4; j++)
|
||||
random_byte[j] = hw_get_random_byte();
|
||||
ret.word[i] = GETU32(random_byte);
|
||||
}
|
||||
|
||||
if (Big8wBigThan(&ret, &curve.N))
|
||||
ret = Big8wMinusMod(ret, curve.N, curve.N);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief HashTwice = Hash(funcflag||g1||(Hash(g2||g3||ID_A||ID_B||RA||RB)))
|
||||
* t1 = (g2||g3||ID_A||ID_B||RA||RB), t2 = (funcflag||g1||hashvalue)
|
||||
*
|
||||
* @param ID_A id of challenger
|
||||
* @param ID_A_len length of ID_A, byte size
|
||||
* @param ID_B id of responser
|
||||
* @param ID_B_len length of ID_B, byte size
|
||||
* @param RA a pointer of a point in group G1
|
||||
* @param RB a pointer of a point in group G1
|
||||
* @param g1 a pointer of a number in Fq12
|
||||
* @param g2 a pointer of a number in Fq12
|
||||
* @param g3 a pointer of a number in Fq12
|
||||
* @param funcflag defined in SM9, funcflag = 0x82 or 0x83
|
||||
* @param ret unsigned char string, store the result
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void HashTwice(uint8_t* ID_A, uint8_t ID_A_len, uint8_t* ID_B, uint8_t ID_B_len,
|
||||
G1point* RA, G1point* RB,
|
||||
q12* g1, q12* g2, q12* g3, uint8_t funcflag, uint8_t* ret)
|
||||
{
|
||||
uint8_t* t1, *t2;
|
||||
uint32_t i, temp, msglen;
|
||||
|
||||
t1 = (uint8_t*)(malloc(ID_A_len + ID_B_len + BIG8W_BYTESIZE * 12 * 2 + BIG8W_BYTESIZE * 2 * 2));
|
||||
t2 = (uint8_t*)(malloc(1 + BIG8W_BYTESIZE * 12 + SM3OUT_32BYTES));
|
||||
|
||||
i = 0;
|
||||
Q12Intou8string(g2, t1, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
Q12Intou8string(g3, t1, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
|
||||
for (temp = 0; temp < ID_A_len; temp++)
|
||||
t1[i + temp] = ID_A[temp];
|
||||
|
||||
i += temp;
|
||||
|
||||
for (temp = 0; temp < ID_B_len; temp++)
|
||||
t1[i + temp] = ID_B[temp];
|
||||
i += temp;
|
||||
|
||||
Big8wIntou8string(&RA->x, t1, i); // join RA and t1
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&RA->y, t1, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&RB->x, t1, i); // join RB and t1
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
Big8wIntou8string(&RB->y, t1, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
msglen = i;
|
||||
|
||||
t2[0] = funcflag;
|
||||
i = 1;
|
||||
|
||||
Q12Intou8string(g1, t2, i);
|
||||
i += BIG8W_BYTESIZE * 12;
|
||||
|
||||
sm3(t1, msglen, t2 + i);
|
||||
sm3(t2, 1 + BIG8W_BYTESIZE * 12 + SM3OUT_32BYTES, ret);
|
||||
|
||||
free(t1);
|
||||
free(t2);
|
||||
}
|
||||
/**
|
||||
* @brief judge if elements in string are zero
|
||||
*
|
||||
* @param string unsigned char string to be checked
|
||||
* @param stringlen length of string
|
||||
*
|
||||
* @return true if all elements in string is zero; else false
|
||||
*
|
||||
*/
|
||||
bool StringEqualZero(uint8_t* string, uint32_t stringlen)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
|
||||
while (length < stringlen)
|
||||
if (string[length++])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief defined in SM9:H(Z, n); n = curve.N, 255 bits, hlen = 2(therefore temp[i] = 0x01, 0x02)
|
||||
*
|
||||
* @param Z unsigned char string
|
||||
* @param Zlen length of Z
|
||||
* @param funcflag defined in SM9, funcflag = 0x01 or 0x02; H1() or H2()
|
||||
*
|
||||
* @return ret big number
|
||||
*
|
||||
*/
|
||||
big8w H(uint8_t* Z, uint32_t Zlen, uint8_t funcflag)
|
||||
{
|
||||
uint8_t* temp;
|
||||
uint8_t Ha[40];
|
||||
uint8_t Ha2[32];
|
||||
uint32_t ctr = 0x01, i = 0;
|
||||
uint32_t datalen;
|
||||
big8w tmp = curve.N;
|
||||
big16w ret;
|
||||
|
||||
tmp.word[0] -= 1; // tmp = curve.N - 1
|
||||
|
||||
datalen = 1 + Zlen + 4;
|
||||
temp = (uint8_t *)malloc(datalen);
|
||||
memset(temp, 0x00, datalen);
|
||||
memset(ret.word, 0x00, BIG8W_BYTESIZE * 2);
|
||||
|
||||
temp[0] = funcflag; // temp = funcfalg||Z||ctr
|
||||
|
||||
for (i = 0; i < Zlen; i++)
|
||||
temp[i + 1] = Z[i];
|
||||
|
||||
temp[++i] = 0;
|
||||
temp[++i] = 0;
|
||||
temp[++i] = 0;
|
||||
|
||||
temp[++i] = 0x01;
|
||||
sm3(temp, datalen, Ha);
|
||||
|
||||
temp[i] = 0x02;
|
||||
sm3(temp, datalen, Ha2);
|
||||
free(temp);
|
||||
|
||||
for (i = 32; i < 40; i++)
|
||||
Ha[i] = Ha2[i - 32];
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
ret.word[9 - i] = GETU32(Ha + i * 4);
|
||||
|
||||
while (ret.word[i] == 0)
|
||||
i--;
|
||||
ret.length = i;
|
||||
|
||||
tmp = Big16wmod8w(ret, tmp); // tmp = Ha mod (N-1)
|
||||
|
||||
i = 0; // tmp += 1
|
||||
while (tmp.word[0] == 0xffffffff) // if overflow after plus one
|
||||
i++;
|
||||
tmp.word[i]++;
|
||||
if (i) while (i) { // if overflow
|
||||
i--;
|
||||
tmp.word[i] = 0;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief key derive function defined in SM9, baseed of hash function(SM3).
|
||||
*
|
||||
* @param Z unsigned char string
|
||||
* @param Zlen length of Z
|
||||
* @param klen length of key to be derived, bitsize!!!
|
||||
* @param ret unsigned char string to store the key derived.
|
||||
*
|
||||
* @result ret
|
||||
*
|
||||
*/
|
||||
void KDF(uint8_t* Z, uint32_t Zlen, uint32_t klen, uint8_t* ret)
|
||||
{
|
||||
uint8_t* tmp, Ha[32];
|
||||
uint32_t i, round;
|
||||
uint32_t ctr = 0x00000001;
|
||||
|
||||
round = klen >> 8;
|
||||
if (klen & 0xff)
|
||||
round++;
|
||||
|
||||
tmp = (uint8_t*)(malloc(Zlen + sizeof(uint32_t))); // tmp = Z||ctr
|
||||
|
||||
for (i = 0; i < Zlen; i++)
|
||||
tmp[i] = Z[i];
|
||||
|
||||
for (ctr = 1; ctr <= round; ctr++) {
|
||||
tmp[i] = (ctr >> 24) & 0xff;
|
||||
tmp[i+1] = (ctr >> 16) & 0xff;
|
||||
tmp[i+2] = (ctr >> 8) & 0xff;
|
||||
tmp[i+3] = ctr & 0xff;
|
||||
sm3(tmp, Zlen + sizeof(uint32_t), ret + 32 * (ctr - 1));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief SM4 Encrypt Function With ecb mode
|
||||
*
|
||||
* @param message data to be encrypted
|
||||
* @param msglen length of message, byte size
|
||||
* @param key key of SM4 algorithm
|
||||
* @param ciphertext unsigned char string to store the encrypted message
|
||||
*
|
||||
* @result ciphertext
|
||||
*
|
||||
*/
|
||||
void SM4EncryptWithEcbMode(uint8_t* message, uint32_t msglen, uint8_t* key, uint8_t* ciphertext)
|
||||
{
|
||||
sms4_key_t renckey;
|
||||
uint32_t ciphertextlen;
|
||||
sms4_set_encrypt_key(&renckey, key);
|
||||
Sms4EcbEncryptPkcs7Padding(message, msglen, ciphertext, &ciphertextlen, &renckey);
|
||||
}
|
||||
/**
|
||||
* @brief SM4 Decrypt Function
|
||||
*
|
||||
* @param ciphertext encrypted message to be decrypted
|
||||
* @param ciphertextlen length of ciphertext, % 128 == 0
|
||||
* @param message unsigned char string to store decrypted data
|
||||
* @param msglen length of message
|
||||
* @param key key of SM4 algorithm
|
||||
*
|
||||
* @result message
|
||||
*
|
||||
*/
|
||||
void SM4DecryptWithEcbMode(uint8_t* ciphertext, uint32_t ciphertextlen, uint8_t* message, int msglen, uint8_t* key)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
sms4_key_t rdeckey;
|
||||
sms4_set_decrypt_key(&rdeckey, key);
|
||||
Sms4EcbDecryptPkcs7Padding(ciphertext, ciphertextlen, message, &msglen, &rdeckey);
|
||||
}
|
||||
/**
|
||||
* @brief function defined in SM9, e(P, Q)
|
||||
*
|
||||
* @param P a point in group G1
|
||||
* @param Q a point in group G2
|
||||
*
|
||||
* @return a number in Fq12
|
||||
*
|
||||
*/
|
||||
q12 BiLinearPairing(G1point P, G2point Q)
|
||||
{
|
||||
bool flag;
|
||||
uint32_t elem = 0x215d93e, i; // a = 6*t+2 = 0x2400000000215d93e, used in Miller round
|
||||
int bitindex = 25; // index of elem's hightest bit
|
||||
G2point T = Q, Q1, Q2;
|
||||
q12 f;
|
||||
|
||||
// Miller round
|
||||
Q12Zero(&f);
|
||||
f.low.low.low.word[0] = 1;
|
||||
|
||||
f = Q12MultMod(f, f); // 0
|
||||
Line(P, &T, T, 1, &f);
|
||||
|
||||
f = Q12MultMod(f, f); // 0
|
||||
Line(P, &T, T, 1, &f);
|
||||
|
||||
f = Q12MultMod(f, f); // 1
|
||||
Line(P, &T, T, 1, &f);
|
||||
Line(P, &T, Q, 0, &f);
|
||||
|
||||
for (i = 0; i < 36; i++) { // 36 continuous 0
|
||||
f = Q12MultMod(f, f);
|
||||
Line(P, &T, T, 1, &f);
|
||||
}
|
||||
|
||||
for (; bitindex >= 0; bitindex--) { // scan 0x215d93e
|
||||
flag = (elem >> bitindex) & 1;
|
||||
f = Q12MultMod(f, f);
|
||||
Line(P, &T, T, 1, &f);
|
||||
if (flag)
|
||||
Line(P, &T, Q, 0, &f);
|
||||
}
|
||||
|
||||
// Frobenius of Q
|
||||
G2pointFrobenius(Q, &Q1, 1);
|
||||
G2pointFrobenius(Q, &Q2, 2);
|
||||
|
||||
Line(P, &T, Q1, 0, &f);
|
||||
|
||||
Q2.y.high = Big8wMinusMod(curve.q, Q2.y.high, curve.q);
|
||||
Q2.y.low = Big8wMinusMod(curve.q, Q2.y.low, curve.q);
|
||||
Line(P, &T, Q2, 0, &f);
|
||||
|
||||
LastPower(&f);
|
||||
|
||||
return f;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 sm3_test.c
|
||||
* @brief tests of SM3
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <sm3.h>
|
||||
#include <xiuos.h>
|
||||
|
||||
void sm3_test_case(){
|
||||
uint8_t result[SM3_DIGEST_LENGTH] = { 0 };
|
||||
//test case 1
|
||||
KPrintf("\n#################### sm3 test ##########################\n");
|
||||
char *msg = "abc";
|
||||
KPrintf("\n####sm3 test case 1:\n");
|
||||
KPrintf( "%-15s %s\n", "digest message1:",msg);
|
||||
sm3(msg,3,result);
|
||||
KPrintf("%-15s ","digest result1: ");
|
||||
for ( int i = 0 ; i < SM3_DIGEST_LENGTH ; i++){
|
||||
KPrintf("%02x",result[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
//test case 2
|
||||
KPrintf("\n####sm3 test case 2:\n");
|
||||
//msg = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
|
||||
char msg1[64] = { 0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 ,0x61, 0x62, 0x63, 0x64 };
|
||||
KPrintf("digest message2: ");
|
||||
for ( int i = 0 ; i < 64 ; i++){
|
||||
KPrintf("%02x",msg1[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
sm3(msg1, 64,result);
|
||||
KPrintf("digest result2: ");
|
||||
for ( int i = 0 ; i < SM3_DIGEST_LENGTH ; i++){
|
||||
KPrintf("%02x",result[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("\n########################################################\n");
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 sm4_test.c
|
||||
* @brief test for SM4
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <sm4.h>
|
||||
#include <xiuos.h>
|
||||
|
||||
void sm4_test_case(){
|
||||
unsigned char ukey[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe ,0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
|
||||
unsigned char input[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe ,0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
|
||||
uint8_t res[16] = {0} ;
|
||||
uint8_t plaintext[16] = {1};
|
||||
uint8_t ciphertext[16] = {2};
|
||||
int olen = 0;
|
||||
sms4_key_t key;
|
||||
|
||||
//test case 1
|
||||
KPrintf("\n#################### sm4 test ##########################\n");
|
||||
KPrintf("\n####sm4 test case1:\n");
|
||||
KPrintf("plaintext: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x ",input[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("key: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",ukey[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("encryption:\n");
|
||||
sms4_set_encrypt_key(&key, ukey);
|
||||
Sms4EcbEncryptNoPadding(input,16,res,&olen,&key);
|
||||
KPrintf("ciphertext: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",res[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("decryption:\n");
|
||||
sms4_set_decrypt_key(&key, ukey);
|
||||
KPrintf("round key in sms4_set_decrypt_key:\n");
|
||||
for (int i = 0; i < 32; i++){
|
||||
KPrintf("rk%d:%08x\n", i, key.rk[i]);
|
||||
}
|
||||
Sms4EcbDecryptNoPadding(res,16,res,&olen,&key);
|
||||
printf("plaintext: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",res[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
////test case 2
|
||||
KPrintf("\n####sm4 test case2:\n");
|
||||
KPrintf("plaintext: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",input[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("key: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",ukey[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("encrypt 1000000 times:\n");
|
||||
sms4_set_encrypt_key(&key, ukey);
|
||||
memcpy(plaintext, input, 16);
|
||||
for (int i = 0;i< 1000000; i++){
|
||||
Sms4EcbEncryptNoPadding(plaintext,16,ciphertext,&olen,&key);
|
||||
memcpy(plaintext, ciphertext, 16);
|
||||
}
|
||||
KPrintf("ciphertext: ");
|
||||
for (int i = 0; i< 16; i++){
|
||||
KPrintf("%02x",ciphertext[i]);
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("\n########################################################\n");
|
||||
}
|
|
@ -0,0 +1,875 @@
|
|||
/*
|
||||
* 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 sm9_test.c
|
||||
* @brief tests of SM9
|
||||
* @version 1.0
|
||||
* @author AIIT Ubiquitous Team
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <sm9_test.h>
|
||||
|
||||
/**
|
||||
* @brief test of sign and signature verify, data comes from SM9
|
||||
*
|
||||
*/
|
||||
void SignAndVerifyTest()
|
||||
{
|
||||
uint8_t ID_Alice[] = "Alice";
|
||||
uint8_t message[] = "Chinese IBS standard";
|
||||
uint8_t hid = 0x01, msglen = strlen((char*)message);
|
||||
uint8_t *Id_Alice_hid, *msg_w;
|
||||
|
||||
big8w ks, t1, t2, r, h, h1, h2;
|
||||
G1point dsA;
|
||||
G2point Ppub_s, P;
|
||||
q12 t, g, w, u;
|
||||
|
||||
Signature sig;
|
||||
|
||||
//clock_t start, end, end_start;
|
||||
|
||||
Id_Alice_hid = (unsigned char*)(malloc(5 + 1));
|
||||
|
||||
ks.word[0] = 0x1F2DC5F4;
|
||||
ks.word[1] = 0x348A1D5B;
|
||||
ks.word[2] = 0x340F319F;
|
||||
ks.word[3] = 0x80CE0B66;
|
||||
ks.word[4] = 0x87E02CF4;
|
||||
ks.word[5] = 0x45CB54C5;
|
||||
ks.word[6] = 0x8459D785;
|
||||
ks.word[7] = 0x000130E7;
|
||||
|
||||
r.word[0] = 0xDC4B1CBE;
|
||||
r.word[1] = 0xED648835;
|
||||
r.word[2] = 0xC662337A;
|
||||
r.word[3] = 0x2ED15975;
|
||||
r.word[4] = 0xD0096502;
|
||||
r.word[5] = 0x813203DF;
|
||||
r.word[6] = 0x16B06704;
|
||||
r.word[7] = 0x033C86;
|
||||
|
||||
SM9Init();
|
||||
|
||||
KPrintf("------------------------------below is ks---------------------------------\n");
|
||||
Big8wPrint(&ks);
|
||||
|
||||
Ppub_s = G2PointMult(ks, P2);
|
||||
KPrintf("------------------------------below is Ppub_s-----------------------------\n");
|
||||
Big8wPrint(&Ppub_s.x.high);
|
||||
Big8wPrint(&Ppub_s.x.low);
|
||||
Big8wPrint(&Ppub_s.y.high);
|
||||
Big8wPrint(&Ppub_s.y.low);
|
||||
|
||||
JoinIDhid(ID_Alice, 5, hid, Id_Alice_hid);
|
||||
|
||||
t1 = Big8wAddMod(H(Id_Alice_hid, 5 + 1, 0x01), ks, curve.N);
|
||||
KPrintf("------------------------------below is t1---------------------------------\n");
|
||||
Big8wPrint(&t1);
|
||||
|
||||
t2 = Big8wMultMod(ks, Big8wReverse(t1, curve.N), curve.N);
|
||||
KPrintf("------------------------------below is t2---------------------------------\n");
|
||||
Big8wPrint(&t2);
|
||||
|
||||
dsA = G1pointMult(t2, P1);
|
||||
KPrintf("------------------------------below is dsA--------------------------------\n");
|
||||
Big8wPrint(&dsA.x);
|
||||
Big8wPrint(&dsA.y);
|
||||
|
||||
g = BiLinearPairing(P1, Ppub_s);
|
||||
KPrintf("------------------------below is bilineapairing---------------------------\n");
|
||||
Q12Print(&g);
|
||||
|
||||
w = Q12PowerMod(g, r);
|
||||
KPrintf("------------------------------below is w----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
msg_w = (uint8_t*)(malloc(msglen + BIG8W_BYTESIZE * 12));
|
||||
JoinMsgW(message, msglen, &w, msg_w);
|
||||
h = H(msg_w, msglen + BIG8W_BYTESIZE * 12, 0x02);
|
||||
KPrintf("------------------------------below is h----------------------------------\n");
|
||||
Big8wPrint(&h);
|
||||
|
||||
big8w L = Big8wMinusMod(r, h, curve.N);
|
||||
KPrintf("------------------------------below is L----------------------------------\n");
|
||||
Big8wPrint(&L);
|
||||
|
||||
G1point S = G1pointMult(L, dsA);
|
||||
KPrintf("------------------------------below is S----------------------------------\n");
|
||||
Big8wPrint(&S.x);
|
||||
Big8wPrint(&S.y);
|
||||
KPrintf("\n");
|
||||
|
||||
// verify the signature
|
||||
g = BiLinearPairing(P1, Ppub_s);
|
||||
KPrintf("------------------------below is bilineapairing---------------------------\n");
|
||||
Q12Print(&g);
|
||||
|
||||
t = Q12PowerMod(g, h);
|
||||
KPrintf("-----------------------------below is t-----------------------------------\n");
|
||||
Q12Print(&t);
|
||||
|
||||
h1 = H(Id_Alice_hid, 5 + 1, 0x01);
|
||||
KPrintf("-----------------------------below is h1----------------------------------\n");
|
||||
Big8wPrint(&h1);
|
||||
|
||||
P = G2PointAdd(Ppub_s, G2PointMult(h1, P2));
|
||||
KPrintf("------------------------------below is P----------------------------------\n");
|
||||
G2pointPrint(&P);
|
||||
|
||||
u = BiLinearPairing(S, P);
|
||||
KPrintf("------------------------------below is u----------------------------------\n");
|
||||
Q12Print(&u);
|
||||
|
||||
w = Q12MultMod(u, t);
|
||||
KPrintf("------------------------------below is w----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
h2 = H(msg_w, msglen + BIG8W_BYTESIZE * 12, 0x02);
|
||||
KPrintf("------------------------------below is h2---------------------------------\n");
|
||||
Big8wPrint(&h2);
|
||||
KPrintf("------------------------------below is h----------------------------------\n");
|
||||
Big8wPrint(&h);
|
||||
|
||||
if (Big8wEqual(&h2, &h))
|
||||
KPrintf("\nh2 = h, test verify success!\n");
|
||||
|
||||
sig = SM9Sign(message, msglen, dsA, Ppub_s);
|
||||
if (SM9VerifySignature(ID_Alice, 5, hid, message, msglen, sig, Ppub_s))
|
||||
KPrintf("SM9 Sign and VerifySignature API run success!\n");
|
||||
|
||||
|
||||
/*
|
||||
start = clock();
|
||||
Ppub_s = G2PointMult(ks, P2);
|
||||
|
||||
t1 = Big8wAddMod(H(Id_Alice_hid, 5 + 1, 0x01), ks, curve.N);
|
||||
|
||||
t2 = Big8wMultMod(ks, Big8wReverse(t1, curve.N), curve.N);
|
||||
|
||||
dsA = G1pointMult(t2, P1);
|
||||
|
||||
g = BiLinearPairing(P1, Ppub_s);
|
||||
w = Q12PowerMod(g, r);
|
||||
|
||||
JoinMsgW(message, msglen, &w, msg_w);
|
||||
h = H(msg_w, msglen + BIG8W_BYTESIZE * k, 0x02);
|
||||
|
||||
L = Big8wMinusMod(r, h, curve.N);
|
||||
|
||||
S = G1pointMult(L, dsA);
|
||||
|
||||
end = clock();
|
||||
end_start = end - start;
|
||||
KPrintf("\n");
|
||||
KPrintf("runtime of sign in: %d ms\n", end_start);
|
||||
*/
|
||||
|
||||
free(Id_Alice_hid);
|
||||
free(msg_w);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief test Key exchange, data comes from SM9
|
||||
*
|
||||
*/
|
||||
void SM9KeyExchangeTest()
|
||||
{
|
||||
uint8_t ID_Alice[] = "Alice", ID_Bob[] = "Bob";
|
||||
uint8_t hid = 0x02;
|
||||
uint8_t Id_Alice_hid[5+1], ID_Bob_hid[3+1], message[100];
|
||||
|
||||
uint32_t klen = 0x80, i;
|
||||
|
||||
big8w ke, t1, t2, t3, t4, h1, rA, rB;
|
||||
G1point Ppub_e, RA, RB, QA, QB;
|
||||
G2point deA, deB;
|
||||
q12 g1, g2, g3;
|
||||
|
||||
uint8_t *strA, *strB, *SKA, *SKB, *SA, *SB, *S1, *S2;
|
||||
strA = (uint8_t*)(malloc(5 + 3 + BIG8W_BYTESIZE * 2 * 2 + BIG8W_BYTESIZE * 12 * 3));
|
||||
strB = (uint8_t*)(malloc(5 + 3 + BIG8W_BYTESIZE * 2 * 2 + BIG8W_BYTESIZE * 12 * 3));
|
||||
SKA = (uint8_t*)(malloc(klen));
|
||||
SKB = (uint8_t*)(malloc(klen));
|
||||
SA = (uint8_t*)(malloc(256/8));
|
||||
SB = (uint8_t*)(malloc(256/8));
|
||||
S1 = (uint8_t*)(malloc(256/8));
|
||||
S2 = (uint8_t*)(malloc(256/8));
|
||||
|
||||
memset(message, 0x00, 100);
|
||||
|
||||
ke.word[7] = 0x02E65B;
|
||||
ke.word[6] = 0x0762D042;
|
||||
ke.word[5] = 0xF51F0D23;
|
||||
ke.word[4] = 0x542B13ED;
|
||||
ke.word[3] = 0x8CFA2E9A;
|
||||
ke.word[2] = 0x0E720636;
|
||||
ke.word[1] = 0x1E013A28;
|
||||
ke.word[0] = 0x3905E31F;
|
||||
|
||||
rA.word[7] = 0x5879;
|
||||
rA.word[6] = 0xDD1D51E1;
|
||||
rA.word[5] = 0x75946F23;
|
||||
rA.word[4] = 0xB1B41E93;
|
||||
rA.word[3] = 0xBA31C584;
|
||||
rA.word[2] = 0xAE59A426;
|
||||
rA.word[1] = 0xEC1046A4;
|
||||
rA.word[0] = 0xD03B06C8;
|
||||
|
||||
rB.word[7] = 0x018B98;
|
||||
rB.word[6] = 0xC44BEF9F;
|
||||
rB.word[5] = 0x8537FB7D;
|
||||
rB.word[4] = 0x071B2C92;
|
||||
rB.word[3] = 0x8B3BC65B;
|
||||
rB.word[2] = 0xD3D69E1E;
|
||||
rB.word[1] = 0xEE213564;
|
||||
rB.word[0] = 0x905634FE;
|
||||
|
||||
SM9Init();
|
||||
|
||||
Ppub_e = G1pointMult(ke, P1);
|
||||
KPrintf("------------------------------below is Ppub_e-----------------------------\n");
|
||||
Big8wPrint(&Ppub_e.x);
|
||||
Big8wPrint(&Ppub_e.y);
|
||||
|
||||
JoinIDhid(ID_Alice, 5, hid, Id_Alice_hid);
|
||||
t1 = Big8wAddMod(H(Id_Alice_hid, 5 + 1, 0x01), ke, curve.N);
|
||||
KPrintf("-----------------------------below is t1----------------------------------\n");
|
||||
Big8wPrint(&t1);
|
||||
|
||||
t2 = Big8wMultMod(ke, Big8wReverse(t1, curve.N), curve.N);
|
||||
KPrintf("-----------------------------below is t2----------------------------------\n");
|
||||
Big8wPrint(&t2);
|
||||
|
||||
deA = G2PointMult(t2, P2);
|
||||
KPrintf("------------------------------below is deA--------------------------------\n");
|
||||
Big8wPrint(&deA.x.high);
|
||||
Big8wPrint(&deA.x.low);
|
||||
Big8wPrint(&deA.y.high);
|
||||
Big8wPrint(&deA.y.low);
|
||||
|
||||
JoinIDhid(ID_Bob, 3, hid, ID_Bob_hid);
|
||||
|
||||
t3 = Big8wAddMod(H(ID_Bob_hid, 3 + 1, 0x01), ke, curve.N);
|
||||
KPrintf("-----------------------------below is t3----------------------------------\n");
|
||||
Big8wPrint(&t3);
|
||||
|
||||
t4 = Big8wMultMod(ke, Big8wReverse(t3, curve.N), curve.N);
|
||||
KPrintf("-----------------------------below is t4----------------------------------\n");
|
||||
Big8wPrint(&t4);
|
||||
|
||||
deB = G2PointMult(t4, P2);
|
||||
KPrintf("------------------------------below is deB--------------------------------\n");
|
||||
Big8wPrint(&deB.x.high);
|
||||
Big8wPrint(&deB.x.low);
|
||||
Big8wPrint(&deB.y.high);
|
||||
Big8wPrint(&deB.y.low);
|
||||
|
||||
JoinIDhid(ID_Bob, 3, hid, ID_Bob_hid);
|
||||
|
||||
h1 = H(ID_Bob_hid, 3 + 1, 0x01);
|
||||
KPrintf("-----------------------------below is h1----------------------------------\n");
|
||||
Big8wPrint(&h1);
|
||||
|
||||
QB = G1pointAdd(Ppub_e, G1pointMult(h1, P1));
|
||||
KPrintf("-----------------------------below is QB----------------------------------\n");
|
||||
Big8wPrint(&QB.x);
|
||||
Big8wPrint(&QB.y);
|
||||
|
||||
RA = G1pointMult(rA, QB);
|
||||
KPrintf("-----------------------------below is RA----------------------------------\n");
|
||||
Big8wPrint(&RA.x);
|
||||
Big8wPrint(&RA.y);
|
||||
|
||||
JoinIDhid(ID_Alice, 5, hid, Id_Alice_hid);
|
||||
h1 = H(Id_Alice_hid, 5 + 1, 0x01);
|
||||
KPrintf("-----------------------------below is h1----------------------------------\n");
|
||||
Big8wPrint(&h1);
|
||||
|
||||
QA = G1pointAdd(Ppub_e, G1pointMult(h1, P1));
|
||||
KPrintf("-----------------------------below is QA----------------------------------\n");
|
||||
Big8wPrint(&QA.x);
|
||||
Big8wPrint(&QA.y);
|
||||
|
||||
RB = G1pointMult(rB, QA);
|
||||
KPrintf("-----------------------------below is RB----------------------------------\n");
|
||||
Big8wPrint(&RB.x);
|
||||
Big8wPrint(&RB.y);
|
||||
|
||||
g1 = BiLinearPairing(RA, deB);
|
||||
KPrintf("-----------------------------below is g1----------------------------------\n");
|
||||
Q12Print(&g1);
|
||||
|
||||
g2 = BiLinearPairing(Ppub_e, P2);
|
||||
g2 = Q12PowerMod(g2, rB);
|
||||
KPrintf("-----------------------------below is g2----------------------------------\n");
|
||||
Q12Print(&g2);
|
||||
|
||||
g3 = Q12PowerMod(g1, rB);
|
||||
KPrintf("-----------------------------below is g3----------------------------------\n");
|
||||
Q12Print(&g3);
|
||||
|
||||
JoinIDAIDBRARBg123(ID_Alice, 5, ID_Bob, 3, &RA, &RB, &g1, &g2, &g3, strA);
|
||||
|
||||
KDF(strA, 5 + 3 + BIG8W_BYTESIZE * 2 * 2 + BIG8W_BYTESIZE * 12 * 3, klen, SKB);
|
||||
KPrintf("-----------------------------below is SKB---------------------------------\n");
|
||||
for (i = 0; i < klen/8; i++){
|
||||
KPrintf("%02x", SKB[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("-----------------------------below is SB----------------------------------\n");
|
||||
HashTwice(ID_Alice, 5, ID_Bob, 3, &RA, &RB, &g1, &g2, &g3, 0x82, SB);
|
||||
HashTwice(ID_Alice, 5, ID_Bob, 3, &RA, &RB, &g1, &g2, &g3, 0x83, S2);
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", SB[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
g1 = BiLinearPairing(Ppub_e, P2);
|
||||
g1 = Q12PowerMod(g1, rA);
|
||||
KPrintf("-----------------------------below is g1----------------------------------\n");
|
||||
Q12Print(&g1);
|
||||
|
||||
g2 = BiLinearPairing(RB, deA);
|
||||
KPrintf("-----------------------------below is g2----------------------------------\n");
|
||||
Q12Print(&g2);
|
||||
|
||||
g3 = Q12PowerMod(g2, rA);
|
||||
KPrintf("-----------------------------below is g3----------------------------------\n");
|
||||
Q12Print(&g3);
|
||||
|
||||
KPrintf("-----------------------------below is S1----------------------------------\n");
|
||||
HashTwice(ID_Alice, 5, ID_Bob, 3, &RA, &RB, &g1, &g2, &g3, 0x82, S1);
|
||||
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", S1[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KDF(strA, 5 + 3 + BIG8W_BYTESIZE * 2 * 2 + BIG8W_BYTESIZE * 12 * 3, klen, SKA);
|
||||
KPrintf("-----------------------------below is SKA---------------------------------\n");
|
||||
for (i = 0; i < klen/8; i++){
|
||||
KPrintf("%02x", SKA[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
KPrintf("-----------------------------below is SA----------------------------------\n");
|
||||
HashTwice(ID_Alice, 5, ID_Bob, 3, &RA, &RB, &g1, &g2, &g3, 0x83, SA);
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", SA[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("-----------------------------below is S2----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", S2[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
// Following is test of API, random big number generated in SM9KeyExchangeProduceR, so result is different from the former.
|
||||
// To get the same result, you should delete the line "*r = RandomNumGenerate();" in function SM9KeyExchangeR. (or set as note)
|
||||
|
||||
KPrintf("---------------------------SM9 key exchange API test----------------------\n");
|
||||
|
||||
SM9KeyExchangeProduceR(ID_Bob, 3, &rA, &RA, Ppub_e);
|
||||
KPrintf("-----------------------------below is RA----------------------------------\n");
|
||||
Big8wPrint(&RA.x);
|
||||
Big8wPrint(&RA.y);
|
||||
|
||||
SM9KeyExchangeProduceR(ID_Alice, 5, &rB, &RB, Ppub_e);
|
||||
KPrintf("-----------------------------below is RB----------------------------------\n");
|
||||
Big8wPrint(&RB.x);
|
||||
Big8wPrint(&RB.y);
|
||||
|
||||
SM9KeyExchangeProduceKey(&RA, &RB, &rA, klen, ID_Alice, 5, ID_Bob, 3, &g1, &g2, &g3, SKA, true, Ppub_e, deA);
|
||||
KPrintf("-----------------------------below is g1----------------------------------\n");
|
||||
Q12Print(&g1);
|
||||
|
||||
KPrintf("-----------------------------below is g2----------------------------------\n");
|
||||
Q12Print(&g2);
|
||||
|
||||
KPrintf("-----------------------------below is g3----------------------------------\n");
|
||||
Q12Print(&g3);
|
||||
|
||||
KPrintf("-----------------------------below is SKA---------------------------------\n");
|
||||
for (i = 0; i < klen/8; i++){
|
||||
KPrintf("%02x", SKA[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
// g1,g2,g3 changed
|
||||
// SM9KeyExchangeProduceKey(&RA, &RB, &rB, klen, ID_Alice, 5, ID_Bob, 3, &g1, &g2, &g3, SKB, false, Ppub_e, deB);
|
||||
|
||||
SM9KeyExchangeVerifyKey(&g1, &g2, &g3, &RA, &RB, ID_Alice, 5, ID_Bob, 3, S1, SA);
|
||||
KPrintf("-----------------------------below is SA----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", SA[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("-----------------------------below is S1----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", S1[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
SM9KeyExchangeVerifyKey(&g1, &g2, &g3, &RA, &RB, ID_Alice, 5, ID_Bob, 3, SB, S2);
|
||||
KPrintf("-----------------------------below is SB----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", SB[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("-----------------------------below is S2----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++){
|
||||
KPrintf("%02x", S2[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
free(strA);
|
||||
free(strB);
|
||||
free(SKA);
|
||||
free(SKB);
|
||||
free(SA);
|
||||
free(SB);
|
||||
free(S1);
|
||||
free(S2);
|
||||
}
|
||||
/**
|
||||
* @brief test of key package and depackage, data comes from SM9
|
||||
*
|
||||
*/
|
||||
void SM9PackDepackTest()
|
||||
{
|
||||
uint32_t i, c_w_id_len, klen = 0x100;
|
||||
big8w ke, t1, t2, r;
|
||||
G1point Ppub_e, QB, C;
|
||||
G2point deB;
|
||||
q12 g, w;
|
||||
|
||||
uint8_t hid = 0x03;
|
||||
uint8_t ID_Bob[] = "Bob";
|
||||
uint8_t* ID_Bob_hid;
|
||||
uint8_t* K_encap, * c_w_id;
|
||||
|
||||
c_w_id_len = BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + 3;
|
||||
|
||||
ID_Bob_hid= (unsigned char*)(malloc(sizeof(char) * (3 + 1)));
|
||||
K_encap = (unsigned char*)(malloc(32));
|
||||
c_w_id = (unsigned char*)(malloc(c_w_id_len));
|
||||
|
||||
ke.word[7] = 0x01EDEE;
|
||||
ke.word[6] = 0x3778F441;
|
||||
ke.word[5] = 0xF8DEA3D9;
|
||||
ke.word[4] = 0xFA0ACC4E;
|
||||
ke.word[3] = 0x07EE36C9;
|
||||
ke.word[2] = 0x3F9A0861;
|
||||
ke.word[1] = 0x8AF4AD85;
|
||||
ke.word[0] = 0xCEDE1C22;
|
||||
|
||||
r.word[7] = 0x7401;
|
||||
r.word[6] = 0x5F8489C0;
|
||||
r.word[5] = 0x1EF42704;
|
||||
r.word[4] = 0x56F9E647;
|
||||
r.word[3] = 0x5BFB602B;
|
||||
r.word[2] = 0xDE7F33FD;
|
||||
r.word[1] = 0x482AB4E3;
|
||||
r.word[0] = 0x684A6722;
|
||||
|
||||
SM9Init();
|
||||
|
||||
Ppub_e = G1pointMult(ke, P1);
|
||||
KPrintf("-----------------------------below is Ppub_e------------------------------\n");
|
||||
Big8wPrint(&Ppub_e.x);
|
||||
Big8wPrint(&Ppub_e.y);
|
||||
|
||||
JoinIDhid(ID_Bob, 3, hid, ID_Bob_hid);
|
||||
t1 = H(ID_Bob_hid, 3 + 1, 0x01);
|
||||
KPrintf("-----------------------------below is H1()--------------------------------\n");
|
||||
Big8wPrint(&t1);
|
||||
t1 = Big8wAddMod(t1, ke, curve.N);
|
||||
KPrintf("-----------------------------below is t1----------------------------------\n");
|
||||
Big8wPrint(&t1);
|
||||
|
||||
t1 = Big8wReverse(t1, curve.N);
|
||||
t2 = Big8wMultMod(ke, t1, curve.N);
|
||||
KPrintf("-----------------------------below is t2----------------------------------\n");
|
||||
Big8wPrint(&t2);
|
||||
|
||||
deB = G2PointMult(t2, P2);
|
||||
KPrintf("------------------------------below is deB--------------------------------\n");
|
||||
Big8wPrint(&deB.x.high);
|
||||
Big8wPrint(&deB.x.low);
|
||||
Big8wPrint(&deB.y.high);
|
||||
Big8wPrint(&deB.y.low);
|
||||
|
||||
QB = G1pointAdd(
|
||||
G1pointMult(H(ID_Bob_hid, 3 + 1, 0x01), P1),
|
||||
Ppub_e);
|
||||
KPrintf("-----------------------------below is QB----------------------------------\n");
|
||||
Big8wPrint(&QB.x);
|
||||
Big8wPrint(&QB.y);
|
||||
|
||||
C = G1pointMult(r, QB);
|
||||
KPrintf("-----------------------------below is C----------------------------------\n");
|
||||
Big8wPrint(&C.x);
|
||||
Big8wPrint(&C.y);
|
||||
|
||||
g = BiLinearPairing(Ppub_e, P2);
|
||||
KPrintf("-----------------------------below is g----------------------------------\n");
|
||||
Q12Print(&g);
|
||||
|
||||
w = Q12PowerMod(g, r);
|
||||
KPrintf("-----------------------------below is w----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
JoinCwID(&C, &w, ID_Bob, 3, c_w_id);
|
||||
|
||||
KDF(c_w_id, c_w_id_len, klen, K_encap);
|
||||
KPrintf("-----------------------------below is K-----------------------------------\n");
|
||||
for (i = 0; i < klen / 8; i++){
|
||||
KPrintf("%02x", K_encap[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
w = BiLinearPairing(C, deB);
|
||||
KPrintf("-----------------------------below is w'----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
JoinCwID(&C, &w, ID_Bob, 3, c_w_id);
|
||||
|
||||
KDF(c_w_id, c_w_id_len, klen, K_encap);
|
||||
KPrintf("-----------------------------below is K'----------------------------------\n");
|
||||
for (i = 0; i < klen / 8; i++){
|
||||
KPrintf("%02x", K_encap[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
KPrintf("pack and depack done\n");
|
||||
|
||||
free(ID_Bob_hid);
|
||||
free(K_encap);
|
||||
free(c_w_id);
|
||||
}
|
||||
/**
|
||||
* @brief test of encrypt and decrypt with KDF and SM4, data comes from SM9
|
||||
*
|
||||
*/
|
||||
void SM9EncryptDecryptTest()
|
||||
{
|
||||
big8w r, ke, t1, t2;
|
||||
G1point Ppub_e, QB, C1;
|
||||
G2point deB;
|
||||
uint32_t i;
|
||||
uint32_t K1_len = 0x80, K2_len = 0x100, mlen = 0xA0;
|
||||
uint32_t klen = mlen + K2_len;
|
||||
uint32_t c_w_id_len = BIG8W_BYTESIZE * 2 + BIG8W_BYTESIZE * 12 + 3; // len(ID_Bob) = 3;
|
||||
q12 g, w;
|
||||
|
||||
unsigned char hid = 0x03;
|
||||
unsigned char ID_Bob[] = "Bob";
|
||||
unsigned char ID_Bob_hid[4];
|
||||
unsigned char message[] = "Chinese IBE standard";
|
||||
unsigned char *C_w_id;
|
||||
unsigned char *K, *C2, *C3, *C2K2, *C, *C_SM4;
|
||||
unsigned char sm4msg[32];
|
||||
|
||||
memset(sm4msg, 0x00, 32);
|
||||
|
||||
unsigned int Cbyteslen_KDF = (BIG8W_BYTESIZE * 2) + (256 / 8) + (mlen / 8);
|
||||
unsigned int Cbyteslen_SM4 = (BIG8W_BYTESIZE * 2) + (256 / 8) + ((mlen / 128) + 1) * (128 / 8);
|
||||
|
||||
C_w_id = (uint8_t*)(malloc(c_w_id_len));
|
||||
K = (uint8_t*)(malloc(((klen >> 8) + 1) * (256 / 8)));
|
||||
C2 = (uint8_t*)(malloc(mlen / 8));
|
||||
C3 = (uint8_t*)(malloc(256 / 8));
|
||||
C2K2 = (uint8_t*)(malloc(mlen/8 + K2_len/8));
|
||||
C = (uint8_t*)(malloc(Cbyteslen_KDF));
|
||||
C_SM4 = (uint8_t *)(malloc(Cbyteslen_SM4));
|
||||
|
||||
r.word[7] = 0xAAC0;
|
||||
r.word[6] = 0x541779C8;
|
||||
r.word[5] = 0xFC45E3E2;
|
||||
r.word[4] = 0xCB25C12B;
|
||||
r.word[3] = 0x5D2576B2;
|
||||
r.word[2] = 0x129AE8BB;
|
||||
r.word[1] = 0x5EE2CBE5;
|
||||
r.word[0] = 0xEC9E785C;
|
||||
|
||||
ke.word[7] = 0x01EDEE;
|
||||
ke.word[6] = 0x3778F441;
|
||||
ke.word[5] = 0xF8DEA3D9;
|
||||
ke.word[4] = 0xFA0ACC4E;
|
||||
ke.word[3] = 0x07EE36C9;
|
||||
ke.word[2] = 0x3F9A0861;
|
||||
ke.word[1] = 0x8AF4AD85;
|
||||
ke.word[0] = 0xCEDE1C22;
|
||||
|
||||
SM9Init();
|
||||
|
||||
Ppub_e = G1pointMult(ke, P1);
|
||||
KPrintf("-----------------------------below is Ppub_e------------------------------\n");
|
||||
Big8wPrint(&Ppub_e.x);
|
||||
Big8wPrint(&Ppub_e.y);
|
||||
|
||||
JoinIDhid(ID_Bob, 3, hid, ID_Bob_hid);
|
||||
t1 = Big8wAddMod(H(ID_Bob_hid, 3 + 1, 0x01), ke, curve.N);
|
||||
KPrintf("-----------------------------below is t1----------------------------------\n");
|
||||
Big8wPrint(&t1);
|
||||
|
||||
t1 = Big8wReverse(t1, curve.N);
|
||||
t2 = Big8wMultMod(ke, t1, curve.N);
|
||||
KPrintf("-----------------------------below is t2----------------------------------\n");
|
||||
Big8wPrint(&t2);
|
||||
|
||||
deB = G2PointMult(t2, P2);
|
||||
KPrintf("------------------------------below is deB--------------------------------\n");
|
||||
Big8wPrint(&deB.x.high);
|
||||
Big8wPrint(&deB.x.low);
|
||||
Big8wPrint(&deB.y.high);
|
||||
Big8wPrint(&deB.y.low);
|
||||
|
||||
QB = G1pointAdd(
|
||||
G1pointMult(H(ID_Bob_hid, 3 + 1, 0x01), P1),
|
||||
Ppub_e);
|
||||
KPrintf("-----------------------------below is QB----------------------------------\n");
|
||||
Big8wPrint(&QB.x);
|
||||
Big8wPrint(&QB.y);
|
||||
|
||||
C1 = G1pointMult(r, QB);
|
||||
KPrintf("-----------------------------below is C1----------------------------------\n");
|
||||
Big8wPrint(&C1.x);
|
||||
Big8wPrint(&C1.y);
|
||||
|
||||
g = BiLinearPairing(Ppub_e, P2);
|
||||
KPrintf("-----------------------------below is g-----------------------------------\n");
|
||||
Q12Print(&g);
|
||||
|
||||
w = Q12PowerMod(g, r);
|
||||
KPrintf("-----------------------------below is w-----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
JoinCwID(&C1, &w, ID_Bob, 3, C_w_id);
|
||||
KDF(C_w_id, c_w_id_len, klen, K);
|
||||
KPrintf("-----------------------------below is K-----------------------------------\n");
|
||||
for (i = 0; i < klen / 8; i++) {
|
||||
KPrintf("%02x", K[i]);
|
||||
if (((i+1)&0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
XOR(message, mlen / 8, K, C2);
|
||||
|
||||
KPrintf("-----------------------------below is C2----------------------------------\n");
|
||||
for (i = 0; i < mlen / 8; i++) {
|
||||
KPrintf("%02x", C2[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
for (i = 0; i < mlen / 8; i++)
|
||||
C2K2[i] = C2[i];
|
||||
for (; i < (mlen / 8) + (K2_len / 8); i++)
|
||||
C2K2[i] = K[i];
|
||||
|
||||
sm3(C2K2, (mlen / 8) + (K2_len / 8), C3);
|
||||
KPrintf("----------------------------below is C3-----------------------------------\n");
|
||||
for (i = 0; i < 256/8; i++) {
|
||||
KPrintf("%02x", C3[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
i = 0;
|
||||
Big8wIntou8string(&C1.x, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
Big8wIntou8string(&C1.y, C, i);
|
||||
i += BIG8W_BYTESIZE;
|
||||
|
||||
for (; i < BIG8W_BYTESIZE * 2 + (256 / 8); i++)
|
||||
C[i] = C3[i - BIG8W_BYTESIZE * 2];
|
||||
|
||||
for (; i < BIG8W_BYTESIZE * 2 + (256 / 8) + (mlen / 8); i++)
|
||||
C[i] = C2[i - (BIG8W_BYTESIZE * 2 + 256 / 8)];
|
||||
|
||||
KPrintf("----------------------------below is C------------------------------------\n");
|
||||
for (i = 0; i < BIG8W_BYTESIZE * 2 + (256 / 8) + (mlen / 8); i++) {
|
||||
KPrintf("%02x", C[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
// decrypt
|
||||
w = BiLinearPairing(C1, deB);
|
||||
KPrintf("----------------------------below is w'-----------------------------------\n");
|
||||
Q12Print(&w);
|
||||
|
||||
JoinCwID(&C1, &w, ID_Bob, 3, C_w_id);
|
||||
KDF(C_w_id, c_w_id_len, klen, K);
|
||||
KPrintf("----------------------------below is K'----------------------------------\n");
|
||||
for (i = 0; i < (klen / 8); i++) {
|
||||
KPrintf("%02x", K[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
XOR(C2, mlen / 8, K, message);
|
||||
|
||||
KPrintf("----------------------------below is M'----------------------------------\n");
|
||||
for (i = 0; i < mlen / 8; i++) {
|
||||
KPrintf("%02x", message[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
for (i = 0; i < mlen / 8; i++)
|
||||
C2K2[i] = C2[i];
|
||||
for (; i < (mlen / 8) + (K2_len / 8); i++)
|
||||
C2K2[i] = K[i];
|
||||
|
||||
sm3(C2K2, (mlen / 8) + (K2_len / 8), C3);
|
||||
KPrintf("----------------------------below is u-----------------------------------\n");
|
||||
for (i = 0; i < 256 / 8; i++) {
|
||||
KPrintf("%02x", C3[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
KPrintf("decrypted message:\n%s\n", message);
|
||||
|
||||
|
||||
KPrintf("-------------SM9EncryptWithKDF and SM9DecryptWithKDF test----------------\n");
|
||||
SM9EncryptWithKDF(message, mlen, K2_len, ID_Bob, 3, hid, Ppub_e, C);
|
||||
KPrintf("------------------below is C, encrypted message--------------------------\n");
|
||||
for (i = 0; i < Cbyteslen_KDF; i++) {
|
||||
KPrintf("%02x", C[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
SM9DecryptWithKDF(ID_Bob, 3, message, 20 * 8, K2_len, C, deB);
|
||||
KPrintf("---------------below is M, decrypted message in test.c-------------------\n");
|
||||
KPrintf("message:\n%s\n", message);
|
||||
|
||||
KPrintf("-------------SM9EncryptWithSM4 and SM9DecryptWithSM4 test----------------\n");
|
||||
SM9EncryptWithSM4(message, mlen, K1_len, K2_len, ID_Bob, 3, hid, Ppub_e, C_SM4);
|
||||
KPrintf("---------------below is C_SM4 in test.c, encrypted message---------------\n");
|
||||
for (i = 0; i < Cbyteslen_SM4; i++) {
|
||||
KPrintf("%02x", C_SM4[i]);
|
||||
if (((i + 1) & 0x3) == 0)
|
||||
KPrintf(" ");
|
||||
if (((i + 1) % 32) == 0)
|
||||
KPrintf("\n");
|
||||
}
|
||||
KPrintf("\n");
|
||||
|
||||
if (!SM9DecryptWithSM4(ID_Bob, 3, sm4msg, (mlen / 8), K1_len, K2_len, C_SM4, Cbyteslen_SM4, deB))
|
||||
KPrintf("SM9DecryptWithSM4 failed\n");
|
||||
KPrintf("---------------------below is M, decrypted message-----------------------\n");
|
||||
for (i = 0; i < (mlen / 8); i++)
|
||||
KPrintf("%c", sm4msg[i]);
|
||||
KPrintf("\n");
|
||||
|
||||
free(C_w_id);
|
||||
free(K);
|
||||
free(C2);
|
||||
free(C2K2);
|
||||
free(C3);
|
||||
free(C);
|
||||
free(C_SM4);
|
||||
}
|
||||
|
||||
// int main()
|
||||
// {
|
||||
// //SignAndVerifyTest();
|
||||
// SM9KeyExchangeTest();
|
||||
// //SM9PackDepackTest();
|
||||
// //SM9EncryptDecryptTest();
|
||||
// }
|
|
@ -130,6 +130,10 @@ ifeq ($(CONFIG_CONNECTION_ADAPTER), y)
|
|||
KERNELPATHS += -I$(KERNEL_ROOT)/framework/connection/Adapter/include #
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO), y)
|
||||
KERNELPATHS += -I$(KERNEL_ROOT)/framework/security/crypto/include #
|
||||
endif
|
||||
|
||||
KERNELPATHS += -I$(KERNEL_ROOT)/resources/include #
|
||||
|
||||
ifeq ($(CONFIG_RESOURCES_SPI), y)
|
||||
|
|
Loading…
Reference in New Issue