I'm trying to understand this function sodium_is_zero from the cryptography library libsodium (https://github.com/jedisct1/libsodium):
https://github.com/jedisct1/libsodium/blob/master/src/libsodium/sodium/utils.c#L256-L266
int
sodium_is_zero(const unsigned char *n, const size_t nlen)
{
size_t i;
volatile unsigned char d = 0U;
for (i = 0U; i < nlen; i++) {
d |= n[i];
}
return 1 & ((d - 1) >> 8);
}
Could anyone explain to me why d is volatile and what purpose volatile is serving here?
Related
Im trying to remove value from a set but can't get it to work
this is the struct
struct set {
int capacity;
int size;
char *array;
};
This is how i insert the values in to the set
void set_insert(const int value, set *s)
{
if (!set_member_of(value, s))
{
int bit_in_array = value; // To make the code easier to read
// Increase the capacity if necessary
if (bit_in_array >= s->capacity)
{
int no_of_bytes = bit_in_array / 8 + 1;
s->array = realloc(s->array, no_of_bytes);
for (int i = s->capacity / 8 ; i < no_of_bytes ; i++)
{
s->array[i] = 0;
}
s->capacity = no_of_bytes * 8;
}
// Set the bit
int byte_no = bit_in_array / 8;
int bit = 7 - bit_in_array % 8;
s->array[byte_no] = s->array[byte_no] | 1 << bit;
s->size++;
}
}
This is how i've tried to remove the values. I don't know why but
it completely ruins the set and assigns different values to the
entire array
void set_remove(const int value, set *const s)
{
int byte_no = value / 8;
if(set_member_of(value, s))
{
s->array[byte_no] = 0;
s->size--;
}
}
You didn't post set_member_of, so I had to synthesize it.
The main issue with set_remove is that it is zeroing out all bits in the given byte. You want to and against the complement of the bit mask. So, change this:
s->array[byte_no] = 0;
Into:
s->array[byte_no] &= ~mask;
When I do bit masks, I like to use macros instead of shifts/divides/etc in multiple places.
In set_insert, I think it's easier to make capacity be number of bytes rather than number of bits.
Although char for the array type works, using unsigned char is probably better.
Note that as you define set, under C, it is not a type.
Anyway, here is the refactored code. I've compiled it but not tested it:
#include <stdlib.h>
typedef unsigned char atom;
typedef struct set {
int capacity;
int size;
atom *array;
} set;
#define INDEX(_bitno) ((_bitno) / 8)
#define MASK(_bitno) (7 - ((_bitno) % 8))
int
set_member_of(int bitno,set *s)
{
int byte_no = INDEX(bitno);
atom mask = MASK(bitno);
atom match = 0;
if (byte_no < s->capacity)
match = s->array[byte_no] & mask;
return match;
}
void
set_insert(int bitno, set *s)
{
if (! set_member_of(bitno, s)) {
int newcap = INDEX(bitno + 8);
// Increase the capacity if necessary
if (newcap > s->capacity) {
s->array = realloc(s->array, newcap);
// zero out any new cells
for (int i = s->capacity; i < newcap; ++i)
s->array[i] = 0;
s->capacity = newcap;
}
atom mask = MASK(bitno);
int byte_no = INDEX(bitno);
s->array[byte_no] |= mask;
s->size++;
}
}
void
set_remove(int bitno, set *s)
{
if (set_member_of(bitno, s)) {
int byte_no = INDEX(bitno);
atom mask = MASK(bitno);
s->array[byte_no] &= ~mask;
s->size--;
}
}
memset() is very fast, as it benefits from stosb op code internally.
Is there a function for 16 and 32 bit values which similar efficiently benefits from stosb, stosw and/or stosd?
wmemset() is not portable and does not help on 16 bit values.
There is no such function in standard C, but depending on what you're trying to do, there may be CPU-specific SIMD "intrinsic functions" that you can use to build one. Your mention of stosb makes me think you're using an x86, so review the documentation for the various *mmintrin.h headers and the functions they provide.
Yes it is in many variants.
for example
void *memset16(void *m, uint16_t val, size_t count)
{
uint16_t *buf = m;
while(count--) *buf++ = val;
return m;
}
void *memset32(void *m, uint32_t val, size_t count)
{
uint32_t *buf = m;
while(count--) *buf++ = val;
return m;
}
void *memsetXX(void *m, void *val, size_t size, size_t count)
{
char *buf = m;
while(count--)
{
memcpy(buf, val, size);
buf += size;
}
return m;
}
Safer version:
void *memset16safe(void *m, uint16_t val, size_t count)
{
char *buf = m;
union
{
uint8_t d8[2];
uint16_t d16;
}u16 = {.d16 = val};
while(count--)
{
*buf++ = u16.d8[0];
*buf++ = u16.d8[1];
}
return m;
}
void *memset32(void *m, uint32_t val, size_t count)
{
char *buf = m;
union
{
uint8_t d8[4];
uint32_t d32;
}u32 = {.d32 = val};
while(count--)
{
*buf++ = u32.d8[0];
*buf++ = u32.d8[1];
*buf++ = u32.d8[2];
*buf++ = u32.d8[3];
}
return m;
}
I have an array of values in hexadecimal.
I have pre-calculated CRC-CCITT (0x1d0f) of it which is : 0xD7F2
I wrote an alghoritm based on working crc alghoritm wrote in javascript , which I tested with same entry of data (calculation here).
I rewrote it inC, but unfortunatelly, I'm getting different output than expected, actually: 0xB5DB.
So, my question is: is possible to have problem inside alghoritm? Could wrong data types causing problem?
Here is an example with a simple array of size 2. Calculated result by calculator is 0x9770, Result of my alghoritm is 0x5D80.
Calculation alghorithm:
unsigned int crcTest[2] = {0xB6FE,0x8C4A};
int main (void){
unsigned int crc = doCrc(crcTest,2);
printf("Correct CRC16-CCITT is: 0x9770\n");
printf("Calculated result func : 0x%X\n", crc);
return 0;
}
unsigned int doCrc(unsigned int *data, int size)
{
int i, j;
unsigned int crc = 0x1d0f;
for (i = 0; i < size; i++){
unsigned int xr = data[i] << 8;
crc = crc^xr;
for (j = 0; j < 8; j++)
{
if (crc & 0x8000){
crc = (crc << 1);
crc = crc ^ 0x1021;
}
else{
crc = crc << 1;
}
}
}
crc = crc & 0xFFFF;
return crc;
}
Whole source code main.c : Download here
JavaScript code which actually works :
CRC1D0F: function() {
var str = this.CleanedString;
var crc = 0x1d0f;
for (var c = 0; c < str.length; c++) {
crc ^= str.charCodeAt(c) << 8;
for (var i = 0; i < 8; i++) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc = crc << 1;
}
}
return crc & 0xFFFF;
Your code is almost correct:
It should be:
unsigned int doCrc(unsigned char *data, int size)
instead of:
unsigned int doCrc(unsigned int *data, int size)
This works:
#include <stdio.h>
#include <stdlib.h>
unsigned int doCrc(unsigned char *data, int size)
{
int i, j;
unsigned int crc = 0x1d0f;
for (i = 0; i < size; i++) {
unsigned int xr = data[i] << 8;
crc = crc ^ xr;
for (j = 0; j < 8; j++)
{
if (crc & 0x8000) {
crc = (crc << 1);
crc = crc ^ 0x1021;
}
else {
crc = crc << 1;
}
}
}
crc = crc & 0xFFFF;
return crc;
}
unsigned char data[] = "1234567890";
int main(int argc, char *argv[])
{
printf("%0x\n", doCrc(data, strlen(data)));
}
Expected output:
57d8
which is the same as we get here.
Had a code which was used to test out DDR and it used to work fine with GCC-4.2.4 but after we moved to GCC-4.7.0 bit flips are observed after the below code is executed ; is this due to a bug in the code or I need to handle something for the new compiler ; given below is the code snippet :
int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count) {
unsigned long volatile *p1 = bufa;
unsigned long volatile *p2 = bufb;
unsigned int j, k;
unsigned long q;
size_t i;
char *msgBuf;
for (k = 0; k < UL_LEN; k++) {
q = ONE << k;
for (j = 0; j < 8; j++) {
q = ~q;
p1 = (unsigned long volatile *) bufa;
p2 = (unsigned long volatile *) bufb;
for (i = 0; i < count; i++) {
*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
}
if (compare_regions(bufa, bufb, count)) {
return -1;
}
}
if(!(k % 10))
puts1(".\0");
}
return 0;
}
int compare_regions(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count) {
int r = 0;
size_t i;
unsigned long physaddr;
unsigned long volatile *p1 = bufa;
unsigned long volatile *p2 = bufb;
for (i = 0; i < count; i++, p1++, p2++) {
if (*p1 != *p2) {
if (use_phys) {
physaddr = physaddrbase + (i * sizeof(unsigned long));
} else {
}
r = -1;
}
}
return r;
}
Introduction
I have an algorithm which takes a pointer to a char array. The algorithm first retrieves the length of the array then reverses the array.
The problem
The problem I have is that I want to use this on a wchar_t array. And want to be able to do this without having to copy the whole function, change the name and the type of the argument.
Here is the mentioned function:
void reverseString(char *str){
unsigned int l = getStringLength(str);
int i = 0;
int m = l >> 1;
while(i < m){
str[i] ^= str[l - 1];
str[l - 1] ^= str[i];
str[i] ^= str[l - 1];
i++;
l--;
}
}
From googling and reading on SO this won't be able to use a void pointer (conceptually same thing using a union) since it would leave me with a solution like this, which to me is equally bad as writing separate functions but with different names and argument types:
void reverseString(void *array, short typeSize){
unsigned int l = getArrayLength(array);
int m = l >> 1;
int i = 0;
char *str = 0;
wchar_t *wstr = 0;
if(typeSize == 1){
str = (char *) array;
while(i < m){
str[i] ^= str[l - 1];
str[l - 1] ^= str[i];
str[i] ^= str[l - 1];
i++;
l--;
}
}else if(typeSize == 4){
wstr = (wchar_t *) array;
while(i < m){
wstr[i] ^= wstr[l - 1];
wstr[l - 1] ^= wstr[i];
wstr[i] ^= wstr[l - 1];
i++;
l--;
}
}
}
Note: getStringLength is just a function which loops through the pointer till it gets to '\0' and returns the iteration sum.
The answer
I am looking for an answer which tells me how to do this in a nicer way without having to rewrite the internals of the algorithm, or an answer saying that it won't be possible to do it any other way. I'm not looking for an answer telling me I should use this and that library which does this for me, because I'm not using this in production code, it's purely educational to get a better understanding of how memory management works and other concepts alike.
Edit: The function I showed is just an example, I'm looking for a universal solution to problems with algorithms alike.
Using "generics" in C is likely to produce code that is noticeably slower and more convoluted / difficult to read / difficult to maintain than the original code. Use the preprocessor if you must do this.
My recommendation is to avoid this technique if at all possible: you should really only use char or wchar_t in your program, not a mixture of both! (char or UChar or almost universally preferable since you can choose the encoding, but I digress...)
#define gchar char
#define gstrlen strlen
#define func_name reverse
#include "reverse_impl.h"
#undef gchar
#undef gstrlen
#undef func_name
#define gchar wchar_t
#define gstrlen wstrlen
#define func_name wreverse
#include "reverse_impl.h"
#undef gchar
#undef gstrlen
#undef func_name
Then, in reverse_impl.h:
void func_name(gchar *str)
{
gchar *p = str, *q = str + gstrlen(str), t;
if (p == q)
return;
q--;
for (; p < q; p++, q--) {
t = *p;
*p = *q;
*q = t;
}
}
Also, DO NOT DO THIS:
x ^= y; // bad!
y ^= x;
x ^= y;
It is more difficult to read and quite possibly much slower to execute.
Also, note that both reverse and wreverse will make garbage if you give them Unicode input: reverse will make malformed output and wreverse can switch the diacritics around or totally screw up Hangul, depending on how they're represented.
It's unlikely to be efficient, but you could easily have your void reverseString(void *array, short typeSize) version reverse the elements via trivial pointer arithmetic and memcpys of the relevant size.
Of course, this approach isn't applicable to every algorithm that you want to make type-agnostic. It's not clear from your question whether you only care about this particular algorithm, or algorithms in general.
[As an aside: Note that using an XOR swap is unlikely to be more efficient than doing it "naively". It's certainly less readable!]
... universal solution ...
The solution is to write something like qsort(): all functions that need to know the size of individual values are passed to your own function with pointers to void all over
#include <math.h>
#include <stdio.h>
#include <wchar.h>
void universalReverseArray(void *arr, size_t siz,
size_t (*arrlen)(void*),
void (*swap)(void*, void*))
{
size_t elems = arrlen(arr);
size_t i = 0;
size_t m = elems >> 1;
unsigned char *p = arr;
while(i < m) {
swap(p + i * siz, p + (elems - 1) * siz);
i++;
elems--;
}
}
void cswap(void *a, void *b) {
char *aa = a, *bb = b;
char t = *aa;
*aa = *bb;
*bb = t;
}
void dswap(void *a, void *b) {
double *aa = a, *bb = b;
double t = *aa;
*aa = *bb;
*bb = t;
}
void wswap(void *a, void *b) {
wchar_t *aa = a, *bb = b;
wchar_t t = *aa;
*aa = *bb;
*bb = t;
}
size_t clen(void *arr) {
char *aa = arr;
size_t retval = 0;
while (*aa) {
retval += 1;
aa += 1;
}
return retval;
}
size_t dlen(void *arr) {
double *aa = arr;
size_t retval = 0;
while (fabs(*aa) >= 0.0001) {
retval += 1;
aa += 1;
}
return retval;
}
size_t wlen(void *arr) {
wchar_t *aa = arr;
size_t retval = 0;
while (*aa) {
retval += 1;
aa += 1;
}
return retval;
}
int main(void) {
double x[] = {1, 2, 3, 4, 5, 0};
char y[] = "foobar";
wchar_t z[4];
z[0] = 'a'; z[1] = 'b'; z[2] = 'c'; z[3] = 0;
for (int k=0; k<5; k++) {printf("%f ", x[k]);}
printf("%s ", y);
printf("%ls\n", z);
universalReverseArray(x, sizeof *x, dlen, dswap);
universalReverseArray(y, sizeof *y, clen, cswap);
universalReverseArray(z, sizeof *z, wlen, wswap);
for (int k=0; k<5; k++) {printf("%f ", x[k]);}
printf("%s ", y);
printf("%ls\n", z);
return 0;
}
You can see it "running" on ideone: http://ideone.com/t1iOg