Skip to content

Commit 736562b

Browse files
author
Alan Szepieniec (laptop 'Akaros')
committed
linked big integer arithmetic to algebra routines
1 parent 326ec25 commit 736562b

File tree

9 files changed

+132
-59
lines changed

9 files changed

+132
-59
lines changed

LICENSE

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2016 aszepieniec
3+
Copyright (c) 2017 Alan Szepieniec
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
SOFTWARE.
22+

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ Ansi C library for basic algebra routines for prime finite fields, chiefly targe
99

1010
# TODO
1111
* polynomial and extension field arithmetic
12-
* link big integer routines with finite field arithmetic
12+
* make primality test faster
1313

1414
# How To
15-
* compile: `gcc -o test_algebra test_algebra.c bi.c csprng.c Keccak-readable-and-compact-c89.c -ansi -Wpedantic`
15+
* compile:
16+
* small field unit tests: `gcc -o test_algebra test_algebra.c algebra.c gfp.c csprng.c Keccak-readable-and-compact-c89.c -ansi -Wpedantic`
17+
* big field unit tests: `gcc -o test_algebra test_algebra.c algebra.c bi.c gfbi.c Keccak-readable-and-compact-c89.c csprng.c -DBIG -ansi -Wpedantic`
18+
* big number arithmetic: `gcc -o test_bi test_bi.c bi.c csprng.c Keccak-readable-and-compact-c89.c -ansi -Wpedantic`
19+
* prime sampling benchmark: `gcc -o benchmark_primality benchmark_primality.c bi.c csprng.c Keccak-readable-and-compact-c89.c -ansi -Wpedantic -O3`
1620

algebra.c

+32-10
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,18 @@ int xgcd( int a, int b, int* x, int* y, int* gcd )
4848
*/
4949
gfpmatrix gfpm( unsigned int height, unsigned int width, gfp_element* pdata )
5050
{
51+
int i, j;
5152
gfpmatrix mat;
5253
mat.height = height;
5354
mat.width = width;
5455
mat.data = pdata;
56+
for( i = 0 ; i < height ; ++i )
57+
{
58+
for( j = 0 ; j < width ; ++j )
59+
{
60+
mat.data[i*width + j] = gfp_init(0);
61+
}
62+
}
5563
return mat;
5664
}
5765

@@ -89,9 +97,14 @@ gfpmatrix gfpm_init( unsigned int height, unsigned int width )
8997
*/
9098
int gfpm_destroy( gfpmatrix fm )
9199
{
92-
/*
93-
printf("destroying gfpm object with data member set to memory address %#010x\n", fm.data);
94-
*/
100+
int i, j;
101+
for( i = 0 ; i < fm.height ; ++i )
102+
{
103+
for( j = 0 ; j < fm.width ; ++j )
104+
{
105+
gfp_destroy(fm.data[i*fm.width + j]);
106+
}
107+
}
95108
free(fm.data);
96109
fm.width = 0;
97110
fm.height = 0;
@@ -817,7 +830,6 @@ int gfpm_redech( gfpmatrix mat )
817830
{
818831
continue;
819832
}
820-
821833
gfp_inverse(&inv, mat.data[row*mat.width + col]);
822834

823835
if( gfp_is_one(inv) != 1 )
@@ -1226,15 +1238,27 @@ int gfpm_inverse( gfpmatrix inv, gfpmatrix mat )
12261238
int gfpm_print( gfpmatrix mat )
12271239
{
12281240
unsigned int i, j;
1241+
printf("[");
12291242
for( i = 0 ; i < mat.height ; ++i )
12301243
{
1244+
printf("[");
12311245
for( j = 0 ; j < mat.width ; ++j )
12321246
{
12331247
gfp_print(mat.data[i*mat.width+j]);
1234-
printf(" ");
1248+
if( j < mat.width - 1 )
1249+
{
1250+
printf(",");
1251+
printf(" ");
1252+
}
1253+
}
1254+
printf("]");
1255+
if( i < mat.height - 1 )
1256+
{
1257+
printf(",");
1258+
printf("\n");
12351259
}
1236-
printf("\n");
12371260
}
1261+
printf("]\n");
12381262
}
12391263

12401264
/**
@@ -1280,9 +1304,7 @@ hqsystem hqs_init( unsigned int n, unsigned int m )
12801304
hqs.quadratic_forms = malloc(sizeof(gfpmatrix) * m);
12811305
for( i = 0 ; i < m ; ++i )
12821306
{
1283-
hqs.quadratic_forms[i].data = malloc(n*n*sizeof(gfp_element));
1284-
hqs.quadratic_forms[i].width = n;
1285-
hqs.quadratic_forms[i].height = n;
1307+
hqs.quadratic_forms[i] = gfpm_init(n,n);
12861308
}
12871309
return hqs;
12881310
}
@@ -1373,7 +1395,7 @@ int hqs_random( hqsystem sys, unsigned char * randomness )
13731395
for( j = 0 ; j < sys.n ; ++j )
13741396
{
13751397
gfp_random(&sys.quadratic_forms[k].data[i*sys.n + j], &randomness[l]);
1376-
l = l + GFP_NUMBYTES + 1;
1398+
l = l + (GFP_NUMBITS + sizeof(unsigned long int) * 8 - 1) / (sizeof(unsigned long int) * 8);
13771399
}
13781400
}
13791401
}

benchmark_primality.c

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ int main( int argc, char ** argv )
5353
csprng_generate(&rng, sizeof(unsigned long int) * num_limbs, (unsigned char*)randomness);
5454
bi_random(&p, bitsize, (unsigned char *)randomness);
5555
bi_setbit(&p, 0, 1);
56+
printf("testing candidate number "); bi_print(p); printf(" for primality ...\n");
5657
}
5758
while( bi_is_prime(p, random_ints, certainty) == 0 );
5859
}

bi.c

+33-14
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,13 @@ int bi_subtract_ignoresign( bi * res, bi lhs, bi rhs )
564564
int bi_subtract( bi * res, bi lhs, bi rhs )
565565
{
566566
int cmp;
567+
568+
if( bi_is_zero(rhs) == 1 )
569+
{
570+
bi_copy(res, lhs);
571+
return 1;
572+
}
573+
567574
cmp = bi_compare_absolute(lhs, rhs);
568575

569576
if( lhs.sign == 1 && rhs.sign == 1 )
@@ -726,7 +733,6 @@ int bi_multiply( bi * res, bi lhs, bi rhs )
726733
unsigned int i;
727734
bi product;
728735

729-
//printf("multiplying lhs %i/%i with rhs %i/%i\n", bi_bitsize(lhs), lhs.num_limbs, bi_bitsize(rhs), rhs.num_limbs);
730736
if( rhs.num_limbs > lhs.num_limbs )
731737
{
732738
return bi_multiply(res, rhs, lhs);
@@ -1275,12 +1281,12 @@ int bi_random( bi * dest, unsigned int num_bits, unsigned char * randomness )
12751281
}
12761282
}
12771283

1278-
rem = num_bits % (sizeof(unsigned long int) * 8);
1284+
rem = num_bits % 8;
12791285
if( rem == 0 )
12801286
{
1281-
rem = rem + sizeof(unsigned long int) * 8;
1287+
rem = rem + 8;
12821288
}
1283-
dest->data[num_limbs-1] = dest->data[num_limbs-1] >> (sizeof(unsigned long int) * 8 - rem);
1289+
dest->data[num_limbs-1] = dest->data[num_limbs-1] >> (8 - rem);
12841290

12851291
return 1;
12861292
}
@@ -1339,14 +1345,14 @@ int bi_xgcd( bi * x, bi * y, bi * g, bi a, bi b )
13391345

13401346
while( !bi_is_zero(r) )
13411347
{
1342-
//printf("r : %i / %i; s: %i / %i; t: %i / %i\n", bi_bitsize(r), r.num_limbs, bi_bitsize(s), s.num_limbs, bi_bitsize(t), t.num_limbs);
13431348
bi_divide(&quotient, &remainder, old_r, r);
13441349

13451350
/*
13461351
printf("numerator: "); bi_print_bitstring(old_r); printf("\n");
13471352
printf("divisor: "); bi_print_bitstring(r); printf("\n");
13481353
printf("quotient: "); bi_print_bitstring(quotient); printf("\n");
13491354
printf("remainder: "); bi_print_bitstring(remainder); printf("\n");
1355+
getchar();
13501356
*/
13511357

13521358
/**/
@@ -1814,7 +1820,7 @@ int bi_getbit( bi integer, int bit_index )
18141820
/**
18151821
* bi_print
18161822
* Send the decimal representation of this integer to stdout.
1817-
* TODO: debig
1823+
* TODO: debug
18181824
*/
18191825
int bi_print( bi integer )
18201826
{
@@ -1824,25 +1830,38 @@ int bi_print( bi integer )
18241830
int numdigits;
18251831
int bitsize;
18261832

1833+
if( bi_is_zero(integer) == 1 )
1834+
{
1835+
printf("0");
1836+
return 1;
1837+
}
1838+
1839+
if( integer.sign == -1 )
1840+
{
1841+
printf("-");
1842+
rem1 = bi_init(0);
1843+
bi_copy(&rem1, integer);
1844+
bi_negate(&rem1);
1845+
bi_print(rem1);
1846+
bi_destroy(rem1);
1847+
return 1;
1848+
}
1849+
18271850
bitsize = bi_bitsize(integer);
18281851
expansion = malloc(bi_bitsize(integer));
18291852
numdigits = 0;
18301853
quo = bi_init(0);
18311854
rem1 = bi_init(0);
18321855
rem2 = bi_init(0);
18331856
ten = bi_cast(10);
1834-
bi_copy(&rem2, integer);
1835-
1836-
if( integer.sign == -1 )
1837-
{
1838-
printf("-");
1839-
}
18401857

1858+
bi_copy(&rem2, integer);
18411859

1842-
for( i = 0 ; i < bitsize && bi_is_zero(rem2) == 0 ; ++i )
1860+
bi_one(&quo);
1861+
for( i = 0 ; i < bitsize && bi_is_zero(quo) == 0 ; ++i )
18431862
{
18441863
bi_divide(&quo, &rem1, rem2, ten);
1845-
bi_copy(&rem2, rem1);
1864+
bi_copy(&rem2, quo);
18461865
expansion[numdigits++] = rem1.data[0];
18471866
}
18481867

gfbi.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ int gfp_inverse( gfp_element * res, gfp_element elm )
115115
x = bi_init(0);
116116
y = bi_init(0);
117117
g = bi_init(0);
118-
bi_xgcd(&g, &x, &y, elm, prime_modulus);
118+
bi_xgcd(&x, &y, &g, elm, prime_modulus);
119119
bi_modulo(res, x, prime_modulus);
120120
bi_destroy(x);
121121
bi_destroy(y);

gfp.c

+18
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ int gfp_compare( gfp_element lhs, gfp_element rhs )
7878
return 0;
7979
}
8080

81+
int gfp_is_one( gfp_element elm )
82+
{
83+
if( elm == 1 )
84+
{
85+
return 1;
86+
}
87+
return 0;
88+
}
89+
90+
int gfp_is_zero( gfp_element elm )
91+
{
92+
if( elm == 0 )
93+
{
94+
return 1;
95+
}
96+
return 0;
97+
}
98+
8199
int gfp_add( gfp_element * res, gfp_element lhs, gfp_element rhs )
82100
{
83101
*res = ((int)(lhs) + (int)(rhs)) % GF_PRIME_MODULUS;

0 commit comments

Comments
 (0)