aboutsummaryrefslogtreecommitdiff
path: root/src/util/bits.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/bits.c')
-rw-r--r--src/util/bits.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/util/bits.c b/src/util/bits.c
index e5f28c1..a0a3795 100644
--- a/src/util/bits.c
+++ b/src/util/bits.c
@@ -4,6 +4,7 @@
*/
#include "bits.h"
+#include <misc/types.h>
#include <sha1/sha1.h>
#include "util/memory.h"
@@ -16,6 +17,36 @@ bits_t *bits_new(size_t bit_len) {
return result;
}
+bits_t *bits_new_rand(size_t bit_len) {
+ bits_t *result = bits_new(bit_len);
+ for (size_t i = 0; i < result->allocated; ++i) {
+ if (i == result->allocated - 1) {
+ size_t last_bits = bit_len % 8;
+ result->bits[i] = (unsigned char)random_bits(last_bits)
+ << (8 - last_bits);
+ } else {
+ result->bits[i] = (unsigned char)random_bits(8);
+ }
+ }
+ return result;
+}
+
+void bits_cpy(bits_t *dest, const bits_t *src) {
+ if (src->bitlen == 0) {
+ return;
+ }
+
+ if (src->allocated < dest->allocated) {
+ memset(dest->bits + src->allocated, 0,
+ dest->allocated - src->allocated);
+ } else if (src->allocated > dest->allocated) {
+ dest->bits = try_realloc(dest->bits, src->allocated);
+ }
+ memcpy(dest->bits, src->bits, src->allocated);
+ dest->allocated = src->allocated;
+ dest->bitlen = src->bitlen;
+}
+
bits_t *bits_copy(const bits_t *bits) {
bits_t *result = try_calloc(sizeof(bits_t));
result->bitlen = bits->bitlen;
@@ -49,6 +80,24 @@ bits_t *bits_from_i(GEN i) {
return result;
}
+bits_t *bits_from_i_len(GEN i, size_t bit_len) {
+ pari_sp ltop = avma;
+ GEN bitvec = binary_zv(i);
+ size_t i_len = (size_t)glength(bitvec);
+ bits_t *result = bits_new(bit_len);
+ size_t offset = 0;
+ if (i_len < bit_len) {
+ offset = bit_len - i_len;
+ }
+ for (size_t j = 0; j < bit_len; ++j) {
+ if (j < i_len && gel(bitvec, j + 1) == (GEN)1) {
+ result->bits[(j + offset) / 8] |= 1 << (7 - ((j + offset) % 8));
+ }
+ }
+ avma = ltop;
+ return result;
+}
+
bits_t *bits_from_hex(const char *hex_str) {
size_t nibble_len = strlen(hex_str);
bits_t *result = bits_new(nibble_len * 4);
@@ -102,7 +151,7 @@ GEN bits_to_i(const bits_t *bits) {
if (GET_BIT(bits->bits, i) != 0)
result = addii(result, int2n(bits->bitlen - i - 1));
}
- return gerepileupto(ltop, result);
+ return gerepilecopy(ltop, result);
}
char *bits_to_hex(const bits_t *bits) {