2 * transsip - the telephony toolkit
3 * By Daniel Borkmann <daniel@transsip.org>
4 * Copyright 2012 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
5 * Subject to the GPL, version 2.
6 * Based on Bhaskar Biswas and Nicolas Sendrier McEliece
7 * implementation, LGPL 2.1.
17 struct matrix
*matrix_init(size_t rown
, size_t coln
)
19 struct matrix
*A
= NULL
;
21 A
= xzmalloc(sizeof(*A
));
24 A
->rwdcnt
= (1 + (coln
- 1) / BITS_PER_LONG
);
25 A
->alloc_size
= rown
* A
->rwdcnt
* sizeof(uint32_t);
26 A
->elem
= xzmalloc(A
->alloc_size
);
31 struct matrix
*matrix_init_from_string(size_t rown
, size_t coln
,
32 const unsigned char *str
, size_t len
)
34 struct matrix
*A
= NULL
;
36 A
= xzmalloc(sizeof(*A
));
39 A
->rwdcnt
= (1 + (coln
- 1) / BITS_PER_LONG
);
40 A
->alloc_size
= rown
* A
->rwdcnt
* sizeof(uint32_t);
41 A
->elem
= xmemdup(str
, len
);
43 bug_on(A
->alloc_size
!= len
);
48 void matrix_free(struct matrix
*A
)
54 struct matrix
*matrix_copy(struct matrix
*A
)
59 X
= matrix_init(A
->rown
, A
->coln
);
61 for (i
= 0; i
< A
->rwdcnt
* A
->rown
; ++i
)
62 X
->elem
[i
] = A
->elem
[i
];
67 struct matrix
*matrix_rowxor(struct matrix
*A
, int a
, int b
)
71 for (i
= 0; i
< A
->rwdcnt
; ++i
)
72 A
->elem
[a
* A
->rwdcnt
+ i
] ^= A
->elem
[b
* A
->rwdcnt
+ i
];
77 void matrix_vec_mul(uint32_t *cR
, uint8_t *x
, struct matrix
*A
)
82 memset(cR
, 0, A
->rwdcnt
* sizeof(uint32_t));
85 /* extract the first column in the form of char array */
86 for (i
= 0; i
< A
->rown
; ++i
) {
87 if ((x
[i
/ 8] >> (i
% 8)) & 1) {
88 for (j
= 0; j
< A
->rwdcnt
; ++j
)
96 struct matrix
*matrix_mul(struct matrix
*A
, struct matrix
*B
)
101 bug_on(A
->coln
!= B
->rown
);
103 C
= matrix_init(A
->rown
, B
->coln
);
104 memset(C
->elem
, 0, C
->alloc_size
);
106 for (i
= 0; i
<A
->rown
; ++i
)
107 for (j
= 0; j
< B
->coln
; ++j
)
108 for (k
= 0; k
< A
->coln
; ++k
)
109 if (matrix_coeff(A
, i
, k
) &&
110 matrix_coeff(B
, k
, j
))
111 matrix_change_coeff(C
, i
, j
);
115 uint32_t *matrix_rref(struct matrix
*A
)
117 /* the matrix is reduced from LSB...(from right) */
119 int i
, j
, failcnt
, findrow
, max
;
122 perm
= xmalloc(A
->coln
* sizeof(uint32_t));
124 for (i
= 0; i
< A
->coln
; ++i
)
125 perm
[i
] = i
; /* initialize permutation */
128 for (i
= 0; i
< A
->rown
; ++i
,--max
) {
131 for (j
= i
; j
< A
->rown
; ++j
) {
132 if(matrix_coeff(A
, j
, max
)) {
133 /* not needed as ith row is 0 and jth row is 1 */
134 if (i
!= j
) /* xor to the row.(swap)? */
135 A
= matrix_rowxor(A
, i
, j
);
141 /* if no row with a 1 found then swap last column and
142 * the column with no 1 down */
144 perm
[A
->coln
- A
->rown
- 1 - failcnt
] = max
;
151 perm
[i
+ A
->coln
- A
->rown
] = max
;
152 /* fill the column downwards with 0's */
153 for (j
= i
+ 1; j
< A
->rown
; ++j
) {
154 if (matrix_coeff(A
, j
, max
))
155 /* check the arg. order */
156 A
= matrix_rowxor(A
, j
, i
);
159 /* fill the column with 0's upwards too */
160 for (j
= i
- 1; j
>= 0; --j
) {
161 if (matrix_coeff(A
, j
, max
))
162 A
= matrix_rowxor(A
, j
, i
);