ECC的代码实现

ECC的代码实现

数据校验介绍: 

        通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。

        如果是时序或者电路方面有什么问题的话,错误数据的发生是无法通过数据校验来进行弥补的,而对于受外界干扰而产生的位翻转错误,则可以一定程度上通过HW或者SW的数据校验来进行数据的检测和纠正。

       常用的数据校验算法有CRC校验和ECC校验等,它们的基本原理很相似。

ECC介绍:

        ECC(错误检查和纠正),这种技术也是在原来的数据位上外加校验位来实现的,具体的原理不再描述,大致的描述可以参照:http://blog.csdn.net/nhczp/archive/2007/07/20/1700031.aspx.

        它有一个规律:数据位每增加一倍,ECC只增加一位检验位,也就是说当数据位为16位时ECC位为6位,32位时ECC位为7位,数据位为64位时ECC位为8位,依此类推,数据位每增加一倍,ECC位只增加一位。

附件说明:

附件1:256字节ECC校正1比特错误代码实现

附件2:512字节ECC校正1比特错误代码实现

/*************************************************************************************************************/

附件1:256字节ECC校正1比特错误代码实现

// 256ByteECC071123.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"

//071126
unsigned char dat[]={
0x0  ,0x0 ,0x0 ,0x0  ,0x0 ,0x0  ,0xf  ,0x5a ,0x5a ,0xf  ,0xc  ,0x59 ,0x3  ,0x56 ,0x55 ,0x0  ,
0x65 ,0x30 ,0x33 ,0x66 ,0x3c ,0x69 ,0x6a ,0x3f ,0x3f ,0x6a ,0x69 ,0x3c ,0x66 ,0x33 ,0x30 ,0x65 ,
0x66 ,0x33 ,0x30 ,0x65 ,0x3f ,0x6a ,0x69 ,0x3c ,0x3c ,0x69 ,0x6a ,0x3f ,0x65 ,0x30 ,0x33 ,0x66 ,
0x3  ,0x56 ,0x55 ,0x0  ,0x5a ,0xf  ,0xc  ,0x59 ,0x59 ,0xc  ,0xf  ,0x5a ,0x0  ,0x55 ,0x56 ,0x3  ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0xc  ,0x59 ,0x5a ,0xf  ,0x55 ,0x0  ,0x3  ,0x56 ,0x56 ,0x3  ,0x0  ,0x55 ,0xf  ,0x5a ,0x59 ,0xc  ,
0xf  ,0x5a ,0x59 ,0xc  ,0x56 ,0x3  ,0x0  ,0x55 ,0x55 ,0x0  ,0x3  ,0x56 ,0xc  ,0x59 ,0x5a ,0xf  ,
0x6a ,0x3f ,0x3c ,0x69 ,0x33 ,0x66 ,0x65 ,0x30 ,0x30 ,0x65 ,0x66 ,0x33 ,0x69 ,0x3c ,0x3f ,0x6a ,
0x6a ,0x3f ,0x3c ,0x69 ,0x33 ,0x66 ,0x65 ,0x30 ,0x30 ,0x65 ,0x66 ,0x33 ,0x69 ,0x3c ,0x3f ,0x6a ,
0xf  ,0x5a ,0x59 ,0xc  ,0x56 ,0x3  ,0x0  ,0x55 ,0x55 ,0x0  ,0x3  ,0x56 ,0xc  ,0x59 ,0x5a ,0xf  ,
0xc  ,0x59 ,0x5a ,0xf  ,0x55 ,0x0  ,0x3  ,0x56 ,0x56 ,0x3  ,0x0  ,0x55 ,0xf  ,0x5a ,0x59 ,0xc  ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0x3  ,0x56 ,0x55 ,0x0  ,0x5a ,0xf  ,0xc  ,0x59 ,0x59 ,0xc  ,0xf  ,0x5a ,0x0  ,0x55 ,0x56 ,0x3  ,
0x66 ,0x33 ,0x30 ,0x65 ,0x3f ,0x6a ,0x69 ,0x3c ,0x3c ,0x69 ,0x6a ,0x3f ,0x65 ,0x30 ,0x33 ,0x66 ,
0x65 ,0x30 ,0x33 ,0x66 ,0x3c ,0x69 ,0x6a ,0x3f ,0x3f ,0x6a ,0x69 ,0x3c ,0x66 ,0x33 ,0x30 ,0x65 ,
0x0  ,0x55 ,0x56 ,0x3  ,0x59 ,0xc  ,0xf  ,0x5a ,0x5a ,0xf  ,0xc  ,0x59 ,0x3  ,0x56 ,0x55 ,0x0
};

//071123
unsigned char ECCTable[]={
0x0  ,0x55 ,0x56 ,0x3  ,0x59 ,0xc  ,0xf  ,0x5a ,0x5a ,0xf  ,0xc  ,0x59 ,0x3  ,0x56 ,0x55 ,0x0  ,
0x65 ,0x30 ,0x33 ,0x66 ,0x3c ,0x69 ,0x6a ,0x3f ,0x3f ,0x6a ,0x69 ,0x3c ,0x66 ,0x33 ,0x30 ,0x65 ,
0x66 ,0x33 ,0x30 ,0x65 ,0x3f ,0x6a ,0x69 ,0x3c ,0x3c ,0x69 ,0x6a ,0x3f ,0x65 ,0x30 ,0x33 ,0x66 ,
0x3  ,0x56 ,0x55 ,0x0  ,0x5a ,0xf  ,0xc  ,0x59 ,0x59 ,0xc  ,0xf  ,0x5a ,0x0  ,0x55 ,0x56 ,0x3  ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0xc  ,0x59 ,0x5a ,0xf  ,0x55 ,0x0  ,0x3  ,0x56 ,0x56 ,0x3  ,0x0  ,0x55 ,0xf  ,0x5a ,0x59 ,0xc  ,
0xf  ,0x5a ,0x59 ,0xc  ,0x56 ,0x3  ,0x0  ,0x55 ,0x55 ,0x0  ,0x3  ,0x56 ,0xc  ,0x59 ,0x5a ,0xf  ,
0x6a ,0x3f ,0x3c ,0x69 ,0x33 ,0x66 ,0x65 ,0x30 ,0x30 ,0x65 ,0x66 ,0x33 ,0x69 ,0x3c ,0x3f ,0x6a ,
0x6a ,0x3f ,0x3c ,0x69 ,0x33 ,0x66 ,0x65 ,0x30 ,0x30 ,0x65 ,0x66 ,0x33 ,0x69 ,0x3c ,0x3f ,0x6a ,
0xf  ,0x5a ,0x59 ,0xc  ,0x56 ,0x3  ,0x0  ,0x55 ,0x55 ,0x0  ,0x3  ,0x56 ,0xc  ,0x59 ,0x5a ,0xf  ,
0xc  ,0x59 ,0x5a ,0xf  ,0x55 ,0x0  ,0x3  ,0x56 ,0x56 ,0x3  ,0x0  ,0x55 ,0xf  ,0x5a ,0x59 ,0xc  ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0x3  ,0x56 ,0x55 ,0x0  ,0x5a ,0xf  ,0xc  ,0x59 ,0x59 ,0xc  ,0xf  ,0x5a ,0x0  ,0x55 ,0x56 ,0x3  ,
0x66 ,0x33 ,0x30 ,0x65 ,0x3f ,0x6a ,0x69 ,0x3c ,0x3c ,0x69 ,0x6a ,0x3f ,0x65 ,0x30 ,0x33 ,0x66 ,
0x65 ,0x30 ,0x33 ,0x66 ,0x3c ,0x69 ,0x6a ,0x3f ,0x3f ,0x6a ,0x69 ,0x3c ,0x66 ,0x33 ,0x30 ,0x65 ,
0x0  ,0x55 ,0x56 ,0x3  ,0x59 ,0xc  ,0xf  ,0x5a ,0x5a ,0xf  ,0xc  ,0x59 ,0x3  ,0x56 ,0x55 ,0x0
};

//计算ECC代码
void NandTranResult(unsigned char reg2,unsigned char reg3,unsigned char *ECCCode)
{
 unsigned char temp1,temp2,i,a,b;

 temp1=temp2=0;
 a=b=0x80;

 for(i=0;i<4;i+&#

以下是一个简单的C++代码实现ECC数字签名和验证的过程,以NIST P-256椭圆曲线为例: ```c++ #include <iostream> #include <openssl/ec.h> #include <openssl/obj_mac.h> #include <openssl/ecdsa.h> #include <openssl/evp.h> #include <openssl/sha.h> using namespace std; // 定义椭圆曲线参数 const int curve_nid = NID_X9_62_prime256v1; const int curve_len = 256; // 生成公私钥对 void gen_keypair(EC_KEY* &ec_key, const char* prvkey_file, const char* pubkey_file) { // 创建椭圆曲线 EC_GROUP* ec_group = EC_GROUP_new_by_curve_name(curve_nid); if (ec_group == NULL) { cout << "Error: EC_GROUP_new_by_curve_name" << endl; return; } // 创建密钥对 ec_key = EC_KEY_new(); if (ec_key == NULL) { cout << "Error: EC_KEY_new" << endl; return; } if (!EC_KEY_set_group(ec_key, ec_group)) { cout << "Error: EC_KEY_set_group" << endl; return; } if (!EC_KEY_generate_key(ec_key)) { cout << "Error: EC_KEY_generate_key" << endl; return; } // 保存私钥到文件 FILE* prvkey_fp = fopen(prvkey_file, "w"); if (prvkey_fp == NULL) { cout << "Error: fopen prvkey" << endl; return; } if (!PEM_write_ECPrivateKey(prvkey_fp, ec_key, NULL, NULL, 0, NULL, NULL)) { cout << "Error: PEM_write_ECPrivateKey" << endl; return; } fclose(prvkey_fp); // 保存公钥到文件 FILE* pubkey_fp = fopen(pubkey_file, "w"); if (pubkey_fp == NULL) { cout << "Error: fopen pubkey" << endl; return; } if (!PEM_write_EC_PUBKEY(pubkey_fp, ec_key)) { cout << "Error: PEM_write_EC_PUBKEY" << endl; return; } fclose(pubkey_fp); } // 读取密钥对 void load_keypair(EC_KEY* &ec_key, const char* prvkey_file, const char* pubkey_file) { // 创建椭圆曲线 EC_GROUP* ec_group = EC_GROUP_new_by_curve_name(curve_nid); if (ec_group == NULL) { cout << "Error: EC_GROUP_new_by_curve_name" << endl; return; } // 读取私钥 FILE* prvkey_fp = fopen(prvkey_file, "r"); if (prvkey_fp == NULL) { cout << "Error: fopen prvkey" << endl; return; } ec_key = PEM_read_ECPrivateKey(prvkey_fp, NULL, NULL, NULL); if (ec_key == NULL) { cout << "Error: PEM_read_ECPrivateKey" << endl; return; } fclose(prvkey_fp); // 读取公钥 FILE* pubkey_fp = fopen(pubkey_file, "r"); if (pubkey_fp == NULL) { cout << "Error: fopen pubkey" << endl; return; } EC_POINT* ec_point = EC_POINT_new(ec_group); if (!PEM_read_EC_PUBKEY(pubkey_fp, &ec_point, NULL, NULL)) { cout << "Error: PEM_read_EC_PUBKEY" << endl; return; } if (!EC_KEY_set_public_key(ec_key, ec_point)) { cout << "Error: EC_KEY_set_public_key" << endl; return; } fclose(pubkey_fp); } // 计算消息哈希值 void calc_hash(const char* data, int data_len, unsigned char* hash) { SHA256_CTX sha_ctx; SHA256_Init(&sha_ctx); SHA256_Update(&sha_ctx, data, data_len); SHA256_Final(hash, &sha_ctx); } // 签名 void sign(EC_KEY* ec_key, const unsigned char* hash, int hash_len, unsigned char* sig, int* sig_len) { EVP_MD_CTX* md_ctx = EVP_MD_CTX_new(); EVP_MD_CTX_init(md_ctx); const EVP_MD* md = EVP_sha256(); if (!ECDSA_sign(0, hash, hash_len, sig, sig_len, ec_key)) { cout << "Error: ECDSA_sign" << endl; return; } } // 验证 bool verify(EC_KEY* ec_key, const unsigned char* hash, int hash_len, const unsigned char* sig, int sig_len) { EVP_MD_CTX* md_ctx = EVP_MD_CTX_new(); EVP_MD_CTX_init(md_ctx); const EVP_MD* md = EVP_sha256(); int ret = ECDSA_verify(0, hash, hash_len, sig, sig_len, ec_key); if (ret == 1) { return true; } else if (ret == 0) { cout << "Error: verify failed" << endl; return false; } else { cout << "Error: ECDSA_verify" << endl; return false; } } int main() { // 生成密钥对 EC_KEY* ec_key = NULL; gen_keypair(ec_key, "prvkey.pem", "pubkey.pem"); // 读取密钥对 ec_key = EC_KEY_new(); load_keypair(ec_key, "prvkey.pem", "pubkey.pem"); // 签名和验证 const char* msg = "Hello, ECC!"; unsigned char hash[32]; calc_hash(msg, strlen(msg), hash); unsigned char sig[128]; int sig_len = 0; sign(ec_key, hash, sizeof(hash), sig, &sig_len); bool verify_result = verify(ec_key, hash, sizeof(hash), sig, sig_len); cout << "verify result: " << verify_result << endl; return 0; } ``` 在实际应用中,需要考虑更多的安全问题和性能优化,例如随机数生成、密钥管理、哈希算法选取、安全参数调整等。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值