1 // Copyright 2007,2008,2010 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
10 void bn_print(char *name
, u8
*a
, u32 n
)
14 printf("%s = ", name
);
16 for (i
= 0; i
< n
; i
++)
22 static void bn_zero(u8
*d
, u32 n
)
27 void bn_copy(u8
*d
, u8
*a
, u32 n
)
32 int bn_compare(u8
*a
, u8
*b
, u32 n
)
36 for (i
= 0; i
< n
; i
++) {
46 static u8
bn_add_1(u8
*d
, u8
*a
, u8
*b
, u32 n
)
53 for (i
= n
- 1; i
< n
; i
--) {
54 dig
= a
[i
] + b
[i
] + c
;
62 static u8
bn_sub_1(u8
*d
, u8
*a
, u8
*b
, u32 n
)
69 for (i
= n
- 1; i
< n
; i
--) {
70 dig
= a
[i
] + 255 - b
[i
] + c
;
78 void bn_reduce(u8
*d
, u8
*N
, u32 n
)
80 if (bn_compare(d
, N
, n
) >= 0)
84 void bn_add(u8
*d
, u8
*a
, u8
*b
, u8
*N
, u32 n
)
86 if (bn_add_1(d
, a
, b
, n
))
92 void bn_sub(u8
*d
, u8
*a
, u8
*b
, u8
*N
, u32 n
)
94 if (bn_sub_1(d
, a
, b
, n
))
98 static const u8 inv256
[0x80] = {
99 0x01, 0xab, 0xcd, 0xb7, 0x39, 0xa3, 0xc5, 0xef,
100 0xf1, 0x1b, 0x3d, 0xa7, 0x29, 0x13, 0x35, 0xdf,
101 0xe1, 0x8b, 0xad, 0x97, 0x19, 0x83, 0xa5, 0xcf,
102 0xd1, 0xfb, 0x1d, 0x87, 0x09, 0xf3, 0x15, 0xbf,
103 0xc1, 0x6b, 0x8d, 0x77, 0xf9, 0x63, 0x85, 0xaf,
104 0xb1, 0xdb, 0xfd, 0x67, 0xe9, 0xd3, 0xf5, 0x9f,
105 0xa1, 0x4b, 0x6d, 0x57, 0xd9, 0x43, 0x65, 0x8f,
106 0x91, 0xbb, 0xdd, 0x47, 0xc9, 0xb3, 0xd5, 0x7f,
107 0x81, 0x2b, 0x4d, 0x37, 0xb9, 0x23, 0x45, 0x6f,
108 0x71, 0x9b, 0xbd, 0x27, 0xa9, 0x93, 0xb5, 0x5f,
109 0x61, 0x0b, 0x2d, 0x17, 0x99, 0x03, 0x25, 0x4f,
110 0x51, 0x7b, 0x9d, 0x07, 0x89, 0x73, 0x95, 0x3f,
111 0x41, 0xeb, 0x0d, 0xf7, 0x79, 0xe3, 0x05, 0x2f,
112 0x31, 0x5b, 0x7d, 0xe7, 0x69, 0x53, 0x75, 0x1f,
113 0x21, 0xcb, 0xed, 0xd7, 0x59, 0xc3, 0xe5, 0x0f,
114 0x11, 0x3b, 0x5d, 0xc7, 0x49, 0x33, 0x55, 0xff,
117 static void bn_mon_muladd_dig(u8
*d
, u8
*a
, u8 b
, u8
*N
, u32 n
)
122 u8 z
= -(d
[n
-1] + a
[n
-1]*b
) * inv256
[N
[n
-1]/2];
124 dig
= d
[n
-1] + a
[n
-1]*b
+ N
[n
-1]*z
;
127 for (i
= n
- 2; i
< n
; i
--) {
128 dig
+= d
[i
] + a
[i
]*b
+ N
[i
]*z
;
137 bn_sub_1(d
, d
, N
, n
);
142 void bn_mon_mul(u8
*d
, u8
*a
, u8
*b
, u8
*N
, u32 n
)
149 for (i
= n
- 1; i
< n
; i
--)
150 bn_mon_muladd_dig(t
, a
, b
[i
], N
, n
);
155 void bn_to_mon(u8
*d
, u8
*N
, u32 n
)
159 for (i
= 0; i
< 8*n
; i
++)
160 bn_add(d
, d
, d
, N
, n
);
163 void bn_from_mon(u8
*d
, u8
*N
, u32 n
)
169 bn_mon_mul(d
, d
, t
, N
, n
);
172 static void bn_mon_exp(u8
*d
, u8
*a
, u8
*N
, u32 n
, u8
*e
, u32 en
)
182 for (i
= 0; i
< en
; i
++)
183 for (mask
= 0x80; mask
!= 0; mask
>>= 1) {
184 bn_mon_mul(t
, d
, d
, N
, n
);
185 if ((e
[i
] & mask
) != 0)
186 bn_mon_mul(d
, t
, a
, N
, n
);
192 void bn_mon_inv(u8
*d
, u8
*a
, u8
*N
, u32 n
)
198 bn_sub_1(t
, N
, s
, n
);
199 bn_mon_exp(d
, a
, N
, n
, t
, n
);