• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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