twintig: Be less verbose by default
[svpe-tools.git] / bn.c
blob630bfffe724a728219a14df13cce5116e66bc6f8
1 // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
5 #include <string.h>
6 #include <stdio.h>
8 #include "tools.h"
10 static void bn_print(char *name, u8 *a, u32 n)
12 u32 i;
14 printf("%s = ", name);
16 for (i = 0; i < n; i++)
17 printf("%02x", a[i]);
19 printf("\n");
22 static void bn_zero(u8 *d, u32 n)
24 memset(d, 0, n);
27 static void bn_copy(u8 *d, u8 *a, u32 n)
29 memcpy(d, a, n);
32 int bn_compare(u8 *a, u8 *b, u32 n)
34 u32 i;
36 for (i = 0; i < n; i++) {
37 if (a[i] < b[i])
38 return -1;
39 if (a[i] > b[i])
40 return 1;
43 return 0;
46 void bn_sub_modulus(u8 *a, u8 *N, u32 n)
48 u32 i;
49 u32 dig;
50 u8 c;
52 c = 0;
53 for (i = n - 1; i < n; i--) {
54 dig = N[i] + c;
55 c = (a[i] < dig);
56 a[i] -= dig;
60 void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
62 u32 i;
63 u32 dig;
64 u8 c;
66 c = 0;
67 for (i = n - 1; i < n; i--) {
68 dig = a[i] + b[i] + c;
69 c = (dig >= 0x100);
70 d[i] = dig;
73 if (c)
74 bn_sub_modulus(d, N, n);
76 if (bn_compare(d, N, n) >= 0)
77 bn_sub_modulus(d, N, n);
80 void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
82 u32 i;
83 u8 mask;
85 bn_zero(d, n);
87 for (i = 0; i < n; i++)
88 for (mask = 0x80; mask != 0; mask >>= 1) {
89 bn_add(d, d, d, N, n);
90 if ((a[i] & mask) != 0)
91 bn_add(d, d, b, N, n);
95 void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en)
97 u8 t[512];
98 u32 i;
99 u8 mask;
101 bn_zero(d, n);
102 d[n-1] = 1;
103 for (i = 0; i < en; i++)
104 for (mask = 0x80; mask != 0; mask >>= 1) {
105 bn_mul(t, d, d, N, n);
106 if ((e[i] & mask) != 0)
107 bn_mul(d, t, a, N, n);
108 else
109 bn_copy(d, t, n);
113 // only for prime N -- stupid but lazy, see if I care
114 void bn_inv(u8 *d, u8 *a, u8 *N, u32 n)
116 u8 t[512], s[512];
118 bn_copy(t, N, n);
119 bn_zero(s, n);
120 s[n-1] = 2;
121 bn_sub_modulus(t, s, n);
122 bn_exp(d, a, N, n, t, n);