1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 /* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1
12 * A + B mod f(x) = a xor b
13 * A * 2 mod f(x)
14 */
15
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <gmssl/hex.h>
21 #include <gmssl/gf128.h>
22 #include <gmssl/endian.h>
23 #include <gmssl/error.h>
24
25
gf128_zero(void)26 gf128_t gf128_zero(void)
27 {
28 uint8_t zero[16] = {0};
29 return gf128_from_bytes(zero);
30 }
31
gf128_from_hex(const char * s)32 gf128_t gf128_from_hex(const char *s)
33 {
34 uint8_t bin[16];
35 size_t len;
36 hex_to_bytes(s, strlen(s), bin, &len);
37 return gf128_from_bytes(bin);
38 }
39
gf128_equ_hex(gf128_t a,const char * s)40 int gf128_equ_hex(gf128_t a, const char *s)
41 {
42 uint8_t bin1[16];
43 uint8_t bin2[16];
44 size_t len;
45 hex_to_bytes(s, strlen(s), bin1, &len);
46 gf128_to_bytes(a, bin2);
47 return memcmp(bin1, bin2, sizeof(bin1)) == 0;
48 }
49
gf128_print_bits(gf128_t a)50 void gf128_print_bits(gf128_t a)
51 {
52 int i;
53 for (i = 0; i < 64; i++) {
54 printf("%d", (int)(a.hi % 2));
55 a.hi >>= 1;
56 }
57 for (i = 0; i < 64; i++) {
58 printf("%d", (int)(a.lo % 2));
59 a.lo >>= 1;
60 }
61 printf("\n");
62 }
63
gf128_print(FILE * fp,int fmt,int ind,const char * label,gf128_t a)64 int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a)
65 {
66 uint8_t be[16];
67 int i;
68
69 printf("%s: ", label);
70 gf128_to_bytes(a, be);
71 for (i = 0; i < 16; i++) {
72 printf("%02x", be[i]);
73 }
74 printf("\n");
75 return 1;
76 }
77
reverse_bits(uint64_t a)78 static uint64_t reverse_bits(uint64_t a)
79 {
80 uint64_t r = 0;
81 int i;
82
83 for (i = 0; i < 63; i++) {
84 r |= a & 1;
85 r <<= 1;
86 a >>= 1;
87 }
88 r |= a & 1;
89 return r;
90 }
91
gf128_from_bytes(const uint8_t p[16])92 gf128_t gf128_from_bytes(const uint8_t p[16])
93 {
94 gf128_t r;
95
96 r.lo = GETU64(p);
97 r.hi = GETU64(p + 8);
98
99 r.lo = reverse_bits(r.lo);
100 r.hi = reverse_bits(r.hi);
101 return r;
102 }
103
gf128_to_bytes(gf128_t a,uint8_t p[16])104 void gf128_to_bytes(gf128_t a, uint8_t p[16])
105 {
106 a.lo = reverse_bits(a.lo);
107 a.hi = reverse_bits(a.hi);
108 PUTU64(p, a.lo);
109 PUTU64(p + 8, a.hi);
110 }
111
gf128_add(gf128_t a,gf128_t b)112 gf128_t gf128_add(gf128_t a, gf128_t b)
113 {
114 gf128_t r;
115 r.hi = a.hi ^ b.hi;
116 r.lo = a.lo ^ b.lo;
117 return r;
118 }
119
gf128_mul(gf128_t a,gf128_t b)120 gf128_t gf128_mul(gf128_t a, gf128_t b)
121 {
122 gf128_t r = {0, 0};
123 uint64_t mask = (uint64_t)1 << 63;
124 int i;
125
126 for (i = 0; i < 64; i++) {
127 if (r.hi & mask) {
128 r.hi = r.hi << 1 | r.lo >> 63;
129 r.lo = (r.lo << 1);
130 r.lo ^= 0x87;
131 } else {
132 r.hi = r.hi << 1 | r.lo >> 63;
133 r.lo = r.lo << 1;
134 }
135
136 if (b.hi & mask) {
137 r.hi ^= a.hi;
138 r.lo ^= a.lo;
139 }
140
141 b.hi <<= 1;
142 }
143 for (i = 0; i < 64; i++) {
144 if (r.hi & mask) {
145 r.hi = r.hi << 1 | r.lo >> 63;
146 r.lo = (r.lo << 1) ^ 0x87;
147 } else {
148 r.hi = r.hi << 1 | r.lo >> 63;
149 r.lo = r.lo << 1;
150 }
151
152 if (b.lo & mask) {
153 r.hi ^= a.hi;
154 r.lo ^= a.lo;
155 }
156
157 b.lo <<= 1;
158 }
159
160 return r;
161 }
162
gf128_mul2(gf128_t a)163 gf128_t gf128_mul2(gf128_t a)
164 {
165 gf128_t r;
166
167 if (a.hi & ((uint64_t)1 << 63)) {
168 r.hi = a.hi << 1 | a.lo >> 63;
169 r.lo = a.lo << 1;
170 r.lo ^= 0x87;
171 } else {
172 r.hi = a.hi << 1 | a.lo >> 63;
173 r.lo = a.lo << 1;
174 }
175
176 return r;
177 }
178