microECC - dereferencing pointer to incomplete type - c

When I try to compile this project I receive an error like this:
dereferencing pointer to incomplete type ‘const struct uECC_Curve_t’ uECC_generate_random_int(r, curves[0]->n, BITS_TO_WORDS(curves[0]->num_n_bits));
I searched several times on Stackoverflow a method to solve this error without success. May I ask you what is wrong in this operation? Why cannot I recover the EC curve parameter n in this manner curves[0]->n?
#include "uECC.h"
#include <stdio.h>
#include <string.h>
void vli_print(char *str, uint8_t *vli, unsigned int size)
{
printf("%s ", str);
for (unsigned i = 0; i < size; ++i)
{
printf("%02X ", (unsigned)vli[i]);
}
printf("\n");
}
int main()
{
uint8_t private[32] = {0};
uint8_t public[64] = {0};
unsigned int r[21];
const struct uECC_Curve_t *curves[1];
int num_curves = 0;
#if uECC_SUPPORTS_secp160r1
curves[num_curves++] = uECC_secp160r1();
#endif
uECC_generate_random_int(r, curves[0]->n, BITS_TO_WORDS(curves[0]->num_n_bits));
memset(public, 0, sizeof(public));
if (!uECC_make_key(public, private, curves[0]))
{
printf("uECC_make_key() failed\n");
}
vli_print("Provided public key = ", public, sizeof(public));
vli_print("Private key = ", private, sizeof(private));
return 0;
}
uECC.h
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
uECC.c (I call it during the compilation with gcc, e.g. gcc -o test test.c uECC.c)
struct uECC_Curve_t {
wordcount_t num_words;
wordcount_t num_bytes;
bitcount_t num_n_bits;
uECC_word_t p[uECC_MAX_WORDS];
uECC_word_t n[uECC_MAX_WORDS];
uECC_word_t G[uECC_MAX_WORDS * 2];
uECC_word_t b[uECC_MAX_WORDS];
void (*double_jacobian)(uECC_word_t * X1,
uECC_word_t * Y1,
uECC_word_t * Z1,
uECC_Curve curve);
#if uECC_SUPPORT_COMPRESSED_POINT
void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve);
#endif
void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
#if (uECC_OPTIMIZATION_LEVEL > 0)
void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
#endif
};

Related

Possible stack corruption in C

While trying to pass an argument to a function; the function receives the wrong value thus creating a segmentation fault while trying to use that value
argc and argv in the main function are corrupted before the program even starts
main.c file:
#include <stdio.h>
#include <stdlib.h>
#include "util/BasicTypes.h"
#include "util/IncludeOpengl.h"
#include "util/Vec2.h"
#include "util/Vec3.h"
#include "util/Vec4.h"
#include "util/Vector.h"
#if !(defined(__linux__) || defined(_WIN64))
STATIC_ASSERT(false, unsupported_system)
#endif
i32 main(i32 argc, ch8** argv) {
//u32 a[] = {1, 2, 3, 4};
//u32* b = a;
u32 i;
Vector v;
init_Vector(&v, sizeof(u32));
for (i = 0; i < 4; i++) {
printf("%i\n", i);
Vector_append(&v, &i);
}
for (i = 0; i < Vector_getSize(&v); i++) {
printf("%i\n", Vector_get(&v, i));
}
destruct_Vector(&v);
return 0;
}
vector.c file where i define the vector functions:
#ifndef VECTOR_C
#define VECTOR_C
#include "../util/Vector.h"
#include "../util/BasicTypes.h"
#include "../util/Assert.h"
void init_Vector(Vector* self, u32 elementSize) {
self->elementSize = elementSize;
self->elements = NULL;
self->elementCount = 0;
}
void destruct_Vector(Vector* self) {
if (self->elements) {
heapFree(self->elements);
}
}
void Vector_append(Vector* self, void* element) {
if (self->elements) {
self->elements = heapRealloc(self->elements, self->elementCount + 1);
memcpy(((byte*)self->elements) + (self->elementCount) * self->elementSize, element, self->elementSize);
self->elementCount += 1;
return;
}
else {
self->elements = heapAlloc((usize)self->elementSize);
memcpy(self->elements, element, self->elementSize);
self->elementCount += 1;
return;
}
}
void Vector_remove(Vector* self, u32 id) {
if (id < self->elementCount) {
void* temp = self->elements;
self->elements = heapAlloc((self->elementCount - 1) * self->elementSize);
memcpy(self->elements, temp, id * self->elementSize);
memcpy(((byte*)self->elements) + id * self->elementSize, ((byte*)temp) + (id + 1) * self->elementSize, (self->elementCount - id - 1) * self->elementSize);
self->elementCount -= 1;
}
else {
ASSERT(false, "(Vector_remove) id is not in the list");
}
}
void Vector_insert(Vector* self, void* element, u32 id) {
if (!self->elements && !id) {
self->elements = heapAlloc(self->elementSize);
self->elementCount = 1;
}
else {
if (id < self->elementCount + 1) {
void* temp = self->elements;
self->elements = heapAlloc((self->elementCount - 1) * self->elementSize);
memcpy(self->elements, temp, id * self->elementSize);
memcpy(((byte*)self->elements) + (id + 1) * self->elementSize, ((byte*)temp) + (id) * self->elementSize, (self->elementCount - id - 1) * self->elementSize);
memcpy(((byte*)self->elements), ((byte*)temp), self->elementSize);
self->elementCount += 1;
}
else {
ASSERT(false, "(Vector_insert) id is too far");
}
}
}
void* Vector_get(Vector* self, u32 id) {
return ((byte*)self->elements) + id * self->elementSize;
}
u32 Vector_getSize(Vector* self) {
return self->elementCount;
}
#endif // VECTOR_C
vector.h file the header file for vector.c:
#ifndef VECTOR_H
#define VECTOR_H
#include "../util/BasicTypes.h"
typedef struct Vector {
void* elements;
u32 elementSize;
u32 elementCount;
} Vector;
void init_Vector(Vector* self, u32 elementSize);
void destruct_Vector(Vector* self);
void Vector_append(Vector* self, void* element);
void Vector_remove(Vector* self, u32 id);
void Vector_insert(Vector* self, void* element, u32 id);
void* Vector_get(Vector* self, u32 id);
u32 Vector_getSize(Vector* self);
#endif // VECTOR_H
basictypes.h file where i define some aliases:
#ifndef BASIC_TYPES_H
#define BASIC_TYPES_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef i8 ch8;
typedef i16 ch16;
typedef i32 ch32;
typedef i64 ch64;
typedef u8 uch8;
typedef u16 uch16;
typedef u32 uch32;
typedef u64 uch64;
typedef float f32;
typedef double f64;
typedef long double f128;
typedef u8 byte;
typedef size_t usize;
#endif // BASIC_TYPES_H
typedef i8 ch8; is wrong, since int8_t might likely expand to signed char, which in turn is not directly compatible with char unless you explicitly covert between the two types.
The format of main is not for the programmer to decide, but the compiler. gcc under strict compliance settings (-pedantic-errors) tells you this much:
error: second argument of 'main' should be 'char **' [-Wmain]
Besides, nobody wants to read code based on your own special type system. We have standards for a reason, so use standard C instead:
#include <stdint.h>
....
int main (int argc, char* argv[])
{
uint32_t i;

returning void* for a function/method return

Is it possible to have a function in C return a 'dynamic' return type
example
printResult (NumOrChar());
void* NumOrChar(void) {
// return int or char
}
void printResult (void* input) {
if (isdigit(input)) {
printf("It's a number");
}
else {
printf("It's not a number");
}
Functions can certainly return void *. But that is a specific pointer type with properties that make it suitable for conveying pointers to objects of any type. It is not a general-purpose wildcard type. Moreover, it does not carry any kind of information about the actual type, if any, of the object to which it points, so there is no way to determine that type dynamically. A C++ programmer might describe this situation as C not providing any RTTI.
Instead, you can return a type that can convey objects of a variety of types, known in advance, with a mechanism to discriminate among those. For example,
union num_or_string {
struct { _Bool is_num; };
struct { _Bool _x1; int num; };
struct { _Bool _x2; char *string; };
};
union num_or_string NumOrChar(void) {
// return a union num_or_string containing an int or a char *
}
void printResult (union num_or_string) {
if (num_or_string.is_num) {
printf("It's a number: %d\n", num_or_string.num);
} else {
printf("It's a string: %s\n", num_or_string.string);
}
}
You can use _Generic in some circumstances
int func_int(int *p)
{
printf("%s\n", __FUNCTION__);
return 5; /* does not make too much sense */
}
float func_float(float *p)
{
printf("%s\n", __FUNCTION__);
return 5.0f; /* does not make too much sense */
}
double func_double(double *p)
{
printf("%s\n", __FUNCTION__);
return 5.0; /* does not make too much sense */
}
#define func(p) _Generic((p), \
int *: func_int, \
float *: func_float, \
double *: func_double)(p) \
Instead of having a block of ifs, one can use a structure of function pointers as a virtual table, including to_string. The following dynamically creates the Type, which can be Num or Letter.
#include <stddef.h> /* offsetof */
#include <stdio.h> /* [|s|sn]printf, fgets, stdin */
#include <stdlib.h> /* malloc, free, strtol */
#include <ctype.h> /* isdigit */
#include <errno.h>
#include <assert.h>
struct Type;
typedef void (*TypeToString)(const struct Type *const, char (*const)[32]);
typedef void (*TypeAction)(struct Type *const);
struct Type {
const struct TypeVt *vt;
};
/* Num extends Type. */
struct Num {
struct Type base;
int value;
};
static struct Num *num_upcast(struct Type *const type) {
return (struct Num *)(void *)((char *)type - offsetof(struct Num, base));
}
static const struct Num *const_num_upcast(const struct Type *const type) {
return (const struct Num *)(const void *)((const char *)type
- offsetof(struct Num, base));
}
static void num_to_string(const struct Type *const type, char (*const a)[32]) {
const struct Num *const num = const_num_upcast(type);
snprintf(*a, sizeof *a, "%d", num->value); /* C99. */
}
static void num_delete(struct Type *const type) {
struct Num *const num = num_upcast(type);
free(num);
}
/* Letter extends Type. */
struct Letter {
struct Type base;
char letter;
};
static struct Letter *letter_upcast(struct Type *const type) {
return (struct Letter *)(void *)((char *)type
- offsetof(struct Letter, base));
}
static const struct Letter *const_letter_upcast(const struct Type *const type) {
return (const struct Letter *)(const void *)((const char *)type
- offsetof(struct Letter, base));
}
static void letter_to_string(const struct Type *const t, char (*const a)[32]) {
const struct Letter *const letter = const_letter_upcast(t);
sprintf(*a, "%c", letter->letter);
}
static void letter_delete(struct Type *const type) {
struct Letter *const letter = letter_upcast(type);
free(letter);
}
static const struct TypeVt {
const char *name;
const TypeToString to_string;
const TypeAction delete;
} num_vt = { "num", &num_to_string, &num_delete },
letter_vt = { "char", &letter_to_string, &letter_delete };
static void type_to_string(const struct Type *const t, char (*const a)[32]) {
assert(t);
t->vt->to_string(t, a);
}
static void type_delete(struct Type *const t) {
assert(t);
t->vt->delete(t);
}
static struct Type *num(const int value) {
struct Num *num = malloc(sizeof *num);
if(!num) return 0;
num->base.vt = &num_vt;
num->value = value;
return &num->base;
}
static struct Type *letter(const char letter) {
struct Letter *l = malloc(sizeof *l);
if(!l) return 0;
l->base.vt = &letter_vt;
l->letter = letter;
return &l->base;
}
static struct Type *read_type(void) {
struct Type *type;
char buffer[64];
if(!fgets(buffer, sizeof buffer, stdin)) return 0;
if(isdigit(buffer[0])) {
long n;
errno = 0;
n = strtol(buffer, 0, 0);
if(errno) return 0;
type = num(n);
} else {
type = letter(buffer[0]);
}
return type;
}
int main(void) {
char a[32];
struct Type *type = 0;
int is_success = 0;
do {
if(!(type = read_type())) break;
type_to_string(type, &a);
printf("\"%s\" is of type %s.\n", a, type->vt->name);
is_success = 1;
} while(0); {
if(type) type_delete(type);
}
if(!is_success) return perror("Failure"), EXIT_FAILURE;
return EXIT_SUCCESS;
}
Probably overkill for your function, but as one has more types, this becomes increasingly attractive. One can consider a union of similar spaced types so that it could be allocated entirely on the stack.
$ bin/numorchar
524645 3456542563456
"524645" is of type num.
$ bin/numorchar
6245635724564357652654245634576
Failure: Result too large
$ bin/numorchar
ata gfddsgsdg
"a" is of type char.
$ bin/numorchar
"
" is of type char.
I guess you are speaking about the C# feature (according to my Google search).
In C, it's not possible unless doing it yourself (other answers show examples). It can be easy or hard depending of your needs. You should think about switching to another language if you really want this (they are sometimes called variants in them).

Error in implementing algorithm for C ++: redefinition error & The file is invalid or corrupt

I have received the Derek algorithm in C++
it's code :
#include<stdio.h>
#define HAVE_STRUCT_TIMESPEC
#include<pthread.h>
#define NR_THREAD 2
struct dekker
{
char flag[2];
int turn;
};
void dekker_lock(struct dekker *, int);
void dekker_unlock(struct dekker *, int);
static struct dekker dlock;
static unsigned long result_sum;
void dekker_lock(struct dekker *d, int thid)
{
d->flag[thid] = 1;
while (d->flag[!thid])
{
d->flag[thid] = 0;
while (d->turn != thid) { (void)0; }
d->flag[thid] = 1;
}
}
void dekker_unlock(struct dekker *d, int thid)
{
d->flag[thid] = 0;
d->turn = !thid;
}
static void *thread_routine(void *arg)
{
int i;
int thid = *(int *)arg;
for (i = 0; i < 1000000; i++)
{
dekker_lock(&dlock, thid);
result_sum++;
dekker_unlock(&dlock, thid);
}
return NULL;
}
int main()
{
int i;
pthread_t pth[NR_THREAD];
for (i = 0; i < NR_THREAD; i++) { pthread_create(&pth[i], NULL,
thread_routine, &i); }
for (i = 0; i < NR_THREAD; i++) { pthread_join(pth[i], NULL); }
printf("result = %lu\n", result_sum);
return 0;
}
and i running this code. I get an error : Timespec redefinition error.
So I searched and got answers : Add between library declarations #define HAVE_STRUCT_TIMESPEC
When I add the above sentence and execute it, I also get error. : The file is invalid or corrupt. Can not read from 0x288.
I want to know how to solution this problem. And this solution would be short and simple sentences.

Solve warning: passing 'const void *' to parameter of type 'AV *'

Compiling an XS-module including libmba I cannot solve this warning with my beginners level experience in C:
helmut#Helmuts-MacBook-Air:~/github/LCS-XS$ make
"/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/bin/perl" "/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/ExtUtils/xsubpp" -typemap "/Users/helmut/perl5/perlbrew/perls/perl- 5.18.2/lib/5.18.2/ExtUtils/typemap" XS.xs > XS.xsc && mv XS.xsc XS.c
cc -c -I. -fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe - fstack-protector -I/usr/local/include -I/opt/local/include -O3 - DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" "- I/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE" XS.c
XS.xs:55:26: warning: passing 'const void *' to parameter of type 'AV *' (aka 'struct av *') discards qualifiers
[-Wincompatible-pointer-types-discards-qualifiers]
SV *line = *av_fetch(a, idx, 0);
^
/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE/embed.h:51:46: note: expanded from macro
'av_fetch'
#define av_fetch(a,b,c) Perl_av_fetch(aTHX_ a,b,c)
^
/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE/proto.h:178:44: note: passing argument to
parameter 'av' here
PERL_CALLCONV SV** Perl_av_fetch(pTHX_ AV *av, I32 key, I32 lval)
^
1 warning generated.
The compiled module is working fine. But is there a way to code it without warning?
The relevant parts in LCS/XS.xs:
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <string.h>
#include <mba/diff.h>
#include <mba/diff.c>
/* snipped */
inline
static const void *
_av_idx(const void *a, int idx, void *context)
{
//AV *av = a;
SV *line = *av_fetch(a, idx, 0);
STRLEN klen;
char *key = SvPVbyte(line, klen);
//printf("key: %s\n",key);
return key;
}
/* snipped */
void lcs_LCS(obj, s1, s2)
SV *obj
AV * s1
AV * s2
PREINIT:
struct CTX *ctx = (struct CTX *)SvIVX(SvRV(obj));
PPCODE:
int d, sn, i;
struct varray *ses = varray_new(sizeof(struct diff_edit), NULL);
IV n;
IV m;
n = av_top_index(s1);
m = av_top_index(s2);
// call libmba::diff()
d = diff(s1, 0, n, s2, 0, m, &_av_idx, &_cmp_str, NULL, 0, ses, &sn, NULL);
The part of mba/diff.h
typedef const void *(*idx_fn)(const void *s, int idx, void *context);
And in mba/diff.c:
int
diff(const void *a, int aoff, int n,
const void *b, int boff, int m,
idx_fn idx, cmp_fn cmp, void *context, int dmax,
struct varray *ses, int *sn,
struct varray *buf)
{
Is there a good practice to solve this warning without changing the source of libmba?
SOLVED:
inline
static const void *
_av_idx(const void *a, int idx, void *context)
{
SV *line = *av_fetch((AV *)a, idx, 0);
// ^^^^^^
STRLEN klen;
char *key = SvPVbyte(line, klen);
return key;
}
Well ... in _av_idx you are promising you will not change the contents of the first parameter
inline static const void *_av_idx(const void *a, int idx, void *context)
// ^^^^^
But then you proceed to send that parameter to a function (av_fetch(a, idx, 0)) that does not promise to not change it. That makes your promise a little strange.
Just remove your promise ...
inline static const void *_av_idx(void *a, int idx, void *context)
// no const ^^^^^^^
Edit
Or you could copy the argument to a local variable and pass that
inline
static const void *
_av_idx(const void *a, int idx, void *context)
{
AV *a_copy;
deep_copy(a_copy, a);
if (a_copy != NULL) {
SV *line = *av_fetch(a_copy, idx, 0);
free(a_copy);
} else {
/* error */
}
STRLEN klen;
char *key = SvPVbyte(line, klen);
//printf("key: %s\n",key);
return key;
}

implementing stack in C with generic style

file stack.h
typedef struct
{
void *elems;
int elem_size;
int log_len;
int alloc_len;
void (*free_fn)(void *);
} stack;
void stack_new(stack *s, int elem_size, void (*free_fn)(void *));
void stack_dispose(stack *s);
void stack_push(stack *s, void *value);
void stack_pop(stack *s, void *address);
and the implementation file stack.c
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define assert(condition) if(!condition) printf("assert fail\n");exit(0)
void strfree(void *elem);
int main()
{
stack s;
int i;
char *copy, *top;
const char *friends[] = {"joe", "castiel", "lily"};
stack_new(&s, sizeof(char *), strfree);
for(i=0; i<3; i++)
{
copy = strdup(friends[i]);
stack_push(&s, &cp);
}
for(i=0; i<=3; i++)
{
stack_pop(&s, &top);
printf("%s\n", top);
}
stack_dispose(&s);
return 1;
}
void strfree(void *elem)
{
free(*(char **)elem);
}
void stack_new(stack *s, int elem_size, void (*free_fn)(void *))
{
assert(elem_size > 0);
s->alloc_len = 4;
s->free_fn = free_fn;
s->log_len = 0;
s->elem_size = elem_size;
s->elems = malloc(s->alloc_len * s->elem_size);
assert(s->elems != NULL);
}
void stack_dispose(stack *s)
{
int i;
if(s->free_fn)
{
for(i=0; i<s->log_len; i++)
{
s->free_fn((char *)s->elems + i * s->elem_size);
}
}
free(s->elems);
}
void stack_push(stack *s, void *v)
{
if(s->log_len == s->alloc_len)
{
s->alloc_len *= 2;
s->elems = realloc(s->elems, s->alloc_len*s->elem_size);
assert(s->elems != NULL);
}
memcpy((char *)s->elems+s->log_len*s->elem_size, v, s->elem_size);
s->log_len++;
}
void stack_pop(stack *s, void *address)
{
assert(s->log_len > 0);
void *source = (char *)s->elems + (s->log_len - 1) * s->elem_size;
memcpy(address, source, s->elem_size);
s->log_len--;
}
So it compiles but it doesn't run.
It has a warning about comparison between pointer and integer which comes from the code
assert(s->elems != NULL);
It is broken somewhere, it will not print out the three names defined here
const char *friends[] = {"joe", "castiel", "lily"};
I know the code is bit of too much, but I really wish to get some help, I'm at my wits end here.
One problem is your assert macro:
#define assert(condition) if(!condition) printf("assert fail\n");exit(0)
The exit(0); is executed regardless of whether the condition is true or false (look at the generated code again). If you want assertions, use the standard #include <assert.h>.
Your first identified problem is with:
assert(s->elems != NULL);
Given the definition, this is equivalent to:
if (!s->elems != NULL)
printf("assert fail\n");
exit(0);
The !s->elems is an integer, either 0 or 1, compared with a null pointer constant. Hence the warning. When writing macros, enclose arguments in parentheses. At minimum:
#define assert(condition) if(!(condition)){printf("assert fail\n");exit(1);}
This still isn't a good macro, but at least it will get rid of the first compilation error, and your stack_new() won't exit when it is called just because it is called. Note that it is conventional to exit with a non-zero status when there is a problem — exiting with zero indicates success.
Run your code in a debugger using GDB to see what it is doing line by line. Google "gdb cheat sheet" to get started and compile your code with -g.

Resources