/* * Make test input file */ void make_test_file(const char * file_name) { int fd = open(file_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } int record_count = 100; for (int rec_i = 0; rec_i < record_count; rec_i++) { header_t hdr; for (int i = 0; i < 64; i++) { hdr.key[i] = (unsigned char)random_limit(256); } hdr.size = random_limit( 100 * (1<<20)); hdr.flags = 0; hdr.crc = 0; write_data_to_fd(fd, &hdr, sizeof(hdr)); void* data = calloc(hdr.size, 1); write_data_to_fd(fd, data, hdr.size); free(data); } close(fd); }
/** Make a maze. See maze.h. */ maze_t* make_maze(int nrows, int ncols, long seed) { // Allocate the array of cell objects. if (cells != NULL) free(cells) ; cells = malloc(nrows*ncols*sizeof(cell_t)) ; for (int r=0; r<nrows; ++r) { for (int c=0; c<ncols; ++c) { cells[r*ncols+c].r = r ; cells[r*ncols+c].c = c ; } } srandom(seed) ; // Choose start and end cells at random, ensuring that they are not the // same cell. maze_t* m = malloc(sizeof(maze_t)) ; m->cells = malloc(nrows*ncols*sizeof(unsigned char)) ; m->nrows = nrows ; m->ncols = ncols ; m->start = get_cell(m, random_limit(0, nrows), random_limit(0, ncols)) ; cell_t* end_cell ; do { end_cell = get_cell(m, random_limit(0, nrows), random_limit(0, ncols)) ; } while (end_cell == m->start) ; m->end = end_cell ; // Add all possible walls to the maze. for (int r=0; r<nrows; ++r) { for (int c=0; c<ncols; ++c) { CELL(m, r, c) = EMPTY ; } } // Generate the maze. build_prim(m) ; return m ; }
int sm2_key_gen_ext( sm2_pubkey *pubkey, sm2_prvkey *prvkey, char* prvkeydata, int* prvLen, char* pubkeydata, int* puLen ) { mpz_init(prvkey->s); random_limit(prvkey->s, SUBGRP_ORDER); mpz_mod_BarrettInit(FIELD_P, &pXbufFieldPrime); point_affn_init(prvkey->sG); point_affn_mul(prvkey->sG, GENERATOR, prvkey->s); //init pubkey memset(pubkey, 0, sizeof(sm2_pubkey)); point_affn_init(pubkey->sG); point_affn_mul(pubkey->sG, GENERATOR, prvkey->s); pubkey->ecp = ECPUCMP; if(*puLen < 0x41){ *puLen = 0x41; return -1; } get_data_from_pubkey(pubkey->sG , pubkeydata, (unsigned int *)puLen ); if(*prvLen < 0x20){ *puLen = 0x20; return -1; } get_data_from_prvkey((unsigned int *)prvkey->s, prvkeydata, (unsigned int *)prvLen); //去掉最前的0x04 if (pubkeydata[0] == 0x04) { for (int i = 0; i < *puLen; ++ i) { pubkeydata[i] = pubkeydata[i + 1]; } *puLen -= 1; } return 0; }
int sm2_key_gen(sm2_pubkey *pubkey, sm2_prvkey *prvkey, char* pubkeydata, int* puLen) { mpz_init(prvkey->s); random_limit(prvkey->s, SUBGRP_ORDER); mpz_mod_BarrettInit(FIELD_P, &pXbufFieldPrime); point_affn_init(prvkey->sG); point_affn_mul(prvkey->sG, GENERATOR, prvkey->s); //init pubkey memset(pubkey, 0, sizeof(sm2_pubkey)); point_affn_init(pubkey->sG); point_affn_mul(pubkey->sG, GENERATOR, prvkey->s); pubkey->ecp = ECPUCMP; if(*puLen < 0x41){ *puLen = 0x41; return 0; } get_data_from_pubkey(pubkey->sG , pubkeydata, (unsigned int *)puLen ); return 0; }
/** Build the maze by removing walls according to Prim's algorithm. * * @param maze a maze with all walls present. */ static void build_prim(maze_t* maze) { // MST edges and cells. If (a, b) in mst_edges, then (b, a) not in // mst_edges. (a, b) in mst_edges iff a, b both in mst_cells. list356_t* mst_edges = make_list() ; list356_t* mst_cells = make_list() ; // The frontier. This is the collection of edges between cells in the MST // and cells not in the MST. If (a, b) in frontier, then a in mst_cells // and b not in mst_cells. list356_t* frontier = make_list() ; // Choose two adjacent cells at random to put into the MST, then // populate the frontier accordinately. For simplicitly, choose a // cell in the interior of the maze, then randomly choose a direction // for the other cell. cell_t* start = get_cell(maze, random_limit(1, maze->nrows-1), random_limit(1, maze->ncols-1)); unsigned char direction = 1 << random_limit(0, 4) ; cell_t* next = get_neighbor(maze, start, direction) ; /* debug("Removing (%d, %d) - (%d, %d).\n", start->r, start->c, next->r, next->c) ; */ remove_wall(maze, start, direction) ; edge_t init_edge = (edge_t){start, next} ; lst_add(mst_edges, &init_edge) ; lst_add(mst_cells, start) ; lst_add(mst_cells, next) ; for (int d=0; d<4; ++d) { if (directions[d] != direction && is_cell(maze, start, directions[d])) { cell_t* c = get_neighbor(maze, start, directions[d]) ; edge_t* e = malloc(sizeof(edge_t)) ; e->a = start ; e->b = c ; lst_add(frontier, e) ; } } for (int d=0; d<4; ++d) { if (directions[d] != opposite(direction) && is_cell(maze, next, directions[d])) { cell_t* c = get_neighbor(maze, next, directions[d]) ; edge_t* e = malloc(sizeof(edge_t)) ; e->a = next ; e->b = c ; lst_add(frontier, e) ; } } // As long as we don't have all the cells in the MST, choose an // edge in the frontier at random. Put the edge in the MST // and compute the new edges to add to the frontier. while (lst_size(mst_cells) < (maze->nrows)*(maze->ncols)) { int p = random_limit(0, lst_size(frontier)) ; edge_t* edge = lst_get(frontier, p) ; cell_t* old_cell = edge->a ; cell_t* new_cell = edge->b ; /* debug("Removing (%d, %d) - (%d, %d).\n", old_cell->r, old_cell->c, new_cell->r, new_cell->c) ; */ remove_wall(maze, old_cell, get_direction(old_cell, new_cell)) ; lst_add(mst_edges, edge) ; lst_add(mst_cells, new_cell) ; for (int d=0; d<4; ++d) { unsigned char dir = directions[d] ; if (is_cell(maze, new_cell, dir)) { cell_t* adj_cell = get_neighbor(maze, new_cell, dir) ; edge_t* edge2 = malloc(sizeof(edge_t)) ; edge2->a = new_cell ; edge2->b = adj_cell ; if (lst_contains(mst_cells, adj_cell, cell_cmp)) { lst_remove(frontier, edge2, edge_cmp) ; if (adj_cell != old_cell) free(edge2) ; } else { lst_add(frontier, edge2) ; } } } } }
int sm2_sign ( sm2_prvkey *prvkey, unsigned char *id, unsigned int ilen, unsigned char *message, unsigned int mlen, unsigned char *signature, unsigned int *slen ) { #ifndef MUL_BITS unsigned char xt[FIELD_SIZE_IN_BYTES*2]; #else unsigned char xt[32*2]; #endif mpz_t e, k, s; point_affn_t kG; //unsigned int xlen = sizeof(xt); if( !signature ) { *slen = FIELD_SIZE_IN_BYTES*2; return 0; } if(*slen < (unsigned int)(FIELD_SIZE_IN_BYTES*2)) return 1; sm2_z(id, ilen, GENERATOR, prvkey->sG, xt); // dump_mem(z, sizeof(z), "z"); sm2_hash(xt, SM3_HASH_LEN, message, mlen, NULL, 0, xt); // dump_mem(h, sizeof(h), "h"); mpz_init(e); OS2IP(e, xt, SM3_HASH_LEN); //e NN_BarrettSetBuf(&pXbufSubgrpOrder); mpz_mod(e, e, SUBGRP_ORDER); mpz_init(k); random_limit(k, SUBGRP_ORDER); NN_BarrettSetBuf(&pXbufFieldPrime); #ifdef USE_ECC_256 //mpz_set_str(k, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", 16); #else //mpz_set_str(k, "ADB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F5656460", 16); #endif point_affn_init(kG); point_affn_mul(kG, GENERATOR, k); // dump_point(kG, "kG"); // gmp_printf("x: %Zx\n", x); mpz_BarrettSetBuf(&pXbufSubgrpOrder); //mpz_mod_BarrettInit(SUBGRP_ORDER, &pXbuf); zp_add_mod_p(e, e, kG->x, SUBGRP_ORDER); I2OSP(signature, FIELD_SIZE_IN_BYTES, e); point_affn_clear(kG); mpz_init(s); mpz_add_ui(s, prvkey->s, 1); //1+d_A mpz_invert(s, s, SUBGRP_ORDER); //(1+d_A)^-1 zp_mul_mod_p(e, e, prvkey->s, SUBGRP_ORDER); zp_sub_mod_p(k, k, e, SUBGRP_ORDER); zp_mul_mod_p(s, s, k, SUBGRP_ORDER); //mpz_mod_BarrettInit(FIELD_P, &pXbuf); mpz_BarrettSetBuf(&pXbufFieldPrime); I2OSP(signature+FIELD_SIZE_IN_BYTES, FIELD_SIZE_IN_BYTES, s); *slen = FIELD_SIZE_IN_BYTES*2; mpz_clear(e); mpz_clear(k); mpz_clear(s); return 0; }
int sm2_enc ( sm2_pubkey *pubkey, unsigned char *plaintext, unsigned int plen, unsigned char *ciphertext, unsigned int *clen ) { mpz_t k; point_affn_t kG; unsigned int c1len, xylen; #ifndef MUL_BITS unsigned char tmp[FIELD_SIZE_IN_BYTES*2]; #else unsigned char tmp[32 * 2]; #endif unsigned int i; if( !ciphertext ) { *clen = FIELD_SIZE_IN_BYTES+1+plen+SM3_HASH_LEN; return 0; } else { if( *clen < (FIELD_SIZE_IN_BYTES+1+plen+SM3_HASH_LEN) ) return 1; } mpz_init(k); NN_BarrettSetBuf(&pXbufSubgrpOrder); random_limit(k, SUBGRP_ORDER); NN_BarrettSetBuf(&pXbufFieldPrime); #ifdef USE_ECC_256 //mpz_set_str(k, "4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", 16); #else //mpz_set_str(k, "ADB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F5656467", 16); #endif point_affn_init(kG); point_affn_mul(kG, GENERATOR, k); // dump_point(kG, "kG"); c1len = *clen; EC2OSP(ciphertext,(int *) &c1len, kG, pubkey->ecp); point_affn_clear(kG); point_affn_init(kG); point_affn_mul(kG, pubkey->sG, k); // dump_point(kG, "kG"); mpz_clear(k); xylen = sizeof(tmp); EC2OSP_XY(tmp, (int *)&xylen, kG); point_affn_clear(kG); dump_mem(tmp, 0x30, "tmp"); sm2_hash(tmp, xylen/2, plaintext, plen, tmp+xylen/2, xylen/2, ciphertext+c1len); sm2_KDF1_ex(ciphertext+c1len+SM3_HASH_LEN, plen, tmp, xylen, ALG_HASH_SM3, 1); for(i=0; i<plen; i++) ciphertext[c1len+SM3_HASH_LEN+i] ^= plaintext[i]; *clen = c1len+plen+SM3_HASH_LEN; return 0; }