diff --git a/include/gmssl/gf128.h b/include/gmssl/gf128.h index 80e535f84..ee325fbb6 100644 --- a/include/gmssl/gf128.h +++ b/include/gmssl/gf128.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -27,27 +27,20 @@ extern "C" { #endif -//typedef unsigned __int128 gf128_t; - -// the least significant bit of lo is a_0, the most significant bit of hi is a_127 -// so x^7 + x^2 + x + 1 is 0x87 -typedef struct { - uint64_t lo; - uint64_t hi; -} gf128_t; - - -// Note: send by value is comptabile with uint128_t and sse2 -gf128_t gf128_from_hex(const char *s); -int gf128_equ_hex(gf128_t a, const char *s); -gf128_t gf128_zero(void); -gf128_t gf128_add(gf128_t a, gf128_t b); -gf128_t gf128_mul(gf128_t a, gf128_t b); -gf128_t gf128_mul2(gf128_t a); -gf128_t gf128_from_bytes(const uint8_t p[16]); -void gf128_to_bytes(gf128_t a, uint8_t p[16]); -int gf128_print(FILE *fp, int fmt ,int ind, const char *label, gf128_t a); -void gf128_print_bits(gf128_t a); + +typedef uint64_t gf128_t[2]; + +void gf128_set_zero(gf128_t r); +void gf128_set_one(gf128_t r); +void gf128_add(gf128_t r, const gf128_t a, const gf128_t b); +void gf128_mul(gf128_t r, const gf128_t a, const gf128_t b); +void gf128_mul_by_2(gf128_t r, const gf128_t a); +void gf128_from_bytes(gf128_t r, const uint8_t p[16]); +void gf128_to_bytes(const gf128_t a, uint8_t p[16]); +int gf128_from_hex(gf128_t r, const char *s); +int gf128_equ_hex(const gf128_t a, const char *s); +int gf128_print(FILE *fp, int fmt, int ind, const char *label, const gf128_t a); + #ifdef __cplusplus } diff --git a/src/gf128.c b/src/gf128.c index c123e6537..515062e13 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include #include + static uint64_t reverse_bits(uint64_t a) { uint64_t r = 0; @@ -36,30 +37,19 @@ static uint64_t reverse_bits(uint64_t a) return r; } -gf128_t gf128_zero(void) +void gf128_set_zero(gf128_t r) { - uint8_t zero[16] = {0}; - return gf128_from_bytes(zero); + r[0] = 0; + r[1] = 0; } -gf128_t gf128_from_hex(const char *s) +void gf128_set_one(gf128_t r) { - uint8_t bin[16]; - size_t len; - hex_to_bytes(s, strlen(s), bin, &len); - return gf128_from_bytes(bin); -} - -int gf128_equ_hex(gf128_t a, const char *s) -{ - uint8_t bin1[16]; - uint8_t bin2[16]; - size_t len; - hex_to_bytes(s, strlen(s), bin1, &len); - gf128_to_bytes(a, bin2); - return memcmp(bin1, bin2, sizeof(bin1)) == 0; + r[0] = 1; + r[1] = 0; } +/* void gf128_print_bits(gf128_t a) { int i; @@ -77,8 +67,9 @@ void gf128_print_bits(gf128_t a) } printf("\n"); } +*/ -int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a) +int gf128_print(FILE *fp, int fmt, int ind, const char *label, const gf128_t a) { uint8_t be[16]; int i; @@ -92,102 +83,117 @@ int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a) return 1; } -gf128_t gf128_from_bytes(const uint8_t p[16]) +void gf128_from_bytes(gf128_t r, const uint8_t p[16]) { - gf128_t r; - - r.lo = GETU64(p); - r.hi = GETU64(p + 8); - - r.lo = reverse_bits(r.lo); - r.hi = reverse_bits(r.hi); - return r; + r[0] = reverse_bits(GETU64(p)); + r[1] = reverse_bits(GETU64(p + 8)); } -void gf128_to_bytes(gf128_t a, uint8_t p[16]) +void gf128_to_bytes(const gf128_t a, uint8_t p[16]) { - a.lo = reverse_bits(a.lo); - a.hi = reverse_bits(a.hi); - PUTU64(p, a.lo); - PUTU64(p + 8, a.hi); + PUTU64(p, reverse_bits(a[0])); + PUTU64(p + 8, reverse_bits(a[1])); } -gf128_t gf128_add(gf128_t a, gf128_t b) +void gf128_add(gf128_t r, const gf128_t a, const gf128_t b) { - gf128_t r; - r.hi = a.hi ^ b.hi; - r.lo = a.lo ^ b.lo; - return r; + r[0] = a[0] ^ b[0]; + r[1] = a[1] ^ b[1]; } #ifndef ENABLE_GMUL_AARCH64 -gf128_t gf128_mul(gf128_t a, gf128_t b) +void gf128_mul(gf128_t r, const gf128_t a, const gf128_t b) { - gf128_t r = {0, 0}; - uint64_t mask = (uint64_t)1 << 63; + const uint64_t mask = (uint64_t)1 << 63; + uint64_t b0 = b[0]; + uint64_t b1 = b[1]; + uint64_t r0 = 0; // incase r is a or b + uint64_t r1 = 0; int i; + for (i = 0; i < 64; i++) { - if (r.hi & mask) { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = (r.lo << 1); - r.lo ^= 0x87; + if (r1 & mask) { + r1 = r1 << 1 | r0 >> 63; + r0 = r0 << 1; + r0 ^= 0x87; } else { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = r.lo << 1; + r1 = r1 << 1 | r0 >> 63; + r0 = r0 << 1; } - if (b.hi & mask) { - r.hi ^= a.hi; - r.lo ^= a.lo; + if (b1 & mask) { + r1 ^= a[1]; + r0 ^= a[0]; } - b.hi <<= 1; + b1 <<= 1; } for (i = 0; i < 64; i++) { - if (r.hi & mask) { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = (r.lo << 1) ^ 0x87; + if (r1 & mask) { + r1 = r1 << 1 | r0 >> 63; + r0 = r0 << 1; + r0 ^= 0x87; } else { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = r.lo << 1; + r1 = r1 << 1 | r0 >> 63; + r0 = r0 << 1; } - if (b.lo & mask) { - r.hi ^= a.hi; - r.lo ^= a.lo; + if (b0 & mask) { + r1 ^= a[1]; + r0 ^= a[0]; } - b.lo <<= 1; + b0 <<= 1; } - return r; + r[0] = r0; + r[1] = r1; } -#else - -extern void gmul(uint64_t r[2], const uint64_t a[2], const uint64_t b[2]); +#endif -gf128_t gf128_mul(gf128_t a, gf128_t b) +void gf128_mul_by_2(gf128_t r, const gf128_t a) { - gf128_t r; - gmul(&r, &a, &b); - return r; -} + const uint64_t mask = (uint64_t)1 << 63; -#endif + if (a[1] & mask) { + r[1] = a[1] << 1 | a[0] >> 63; + r[0] = a[0] << 1; + r[0] ^= 0x87; + } else { + r[1] = a[1] << 1 | a[0] >> 63; + r[0] = a[0] << 1; + } +} -gf128_t gf128_mul2(gf128_t a) +int gf128_from_hex(gf128_t r, const char *s) { - gf128_t r; + uint8_t bytes[16]; + size_t len; - if (a.hi & ((uint64_t)1 << 63)) { - r.hi = a.hi << 1 | a.lo >> 63; - r.lo = a.lo << 1; - r.lo ^= 0x87; - } else { - r.hi = a.hi << 1 | a.lo >> 63; - r.lo = a.lo << 1; + if (strlen(s) != sizeof(bytes) * 2) { + error_print(); + return -1; } + if (hex_to_bytes(s, strlen(s), bytes, &len) != 1) { + error_print(); + return -1; + } + gf128_from_bytes(r, bytes); + return 1; +} - return r; +int gf128_equ_hex(const gf128_t a, const char *s) +{ + gf128_t b; + + if (gf128_from_hex(b, s) != 1) { + error_print(); + return -1; + } + if (a[0] != b[0] || a[1] != b[1]) { + return 0; + } + return 1; } + diff --git a/src/gf128_aarch64.S b/src/gf128_aarch64.S index ad4d5f634..939e401c3 100644 --- a/src/gf128_aarch64.S +++ b/src/gf128_aarch64.S @@ -29,9 +29,9 @@ = c + (e0 + w0) * x^64 + (d0 + w1) * f0 */ .text -.globl _gmul +.globl _gf128_mul .align 4 -_gmul: +_gf128_mul: // load (a0, a1) ld1 {v1.2d},[x1] // load (b0, b1) diff --git a/src/ghash.c b/src/ghash.c index e67671574..51d4e8cea 100644 --- a/src/ghash.c +++ b/src/ghash.c @@ -35,48 +35,51 @@ */ void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16]) { - gf128_t H = gf128_from_bytes(h); - gf128_t X = gf128_zero(); + gf128_t H; + gf128_t X; gf128_t L; + gf128_from_bytes(H, h); + gf128_set_zero(X); + PUTU64(out, (uint64_t)aadlen << 3); PUTU64(out + 8, (uint64_t)clen << 3); - L = gf128_from_bytes(out); + gf128_from_bytes(L, out); while (aadlen) { gf128_t A; if (aadlen >= 16) { - A = gf128_from_bytes(aad); + gf128_from_bytes(A, aad); aad += 16; aadlen -= 16; } else { memset(out, 0, 16); memcpy(out, aad, aadlen); - A = gf128_from_bytes(out); + gf128_from_bytes(A, out); aadlen = 0; } - X = gf128_add(X, A); - X = gf128_mul(X, H); + gf128_add(X, X, A); + gf128_mul(X, X, H); } while (clen) { gf128_t C; if (clen >= 16) { - C = gf128_from_bytes(c); + gf128_from_bytes(C, c); c += 16; clen -= 16; } else { memset(out, 0, 16); memcpy(out, c, clen); - C = gf128_from_bytes(out); + gf128_from_bytes(C, out); clen = 0; } - X = gf128_add(X, C); - X = gf128_mul(X, H); + gf128_add(X, X, C); + gf128_mul(X, X, H); } - X = gf128_add(X, L); - H = gf128_mul(X, H); + gf128_add(X, X, L); + gf128_mul(H, H, X); gf128_to_bytes(H, out); } @@ -86,24 +89,24 @@ void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t gf128_t A; memset(ctx, 0, sizeof(*ctx)); - ctx->H = gf128_from_bytes(h); - ctx->X = gf128_zero(); + gf128_from_bytes(ctx->H, h); + gf128_set_zero(ctx->X); ctx->aadlen = aadlen; ctx->clen = 0; while (aadlen) { if (aadlen >= 16) { - A = gf128_from_bytes(aad); + gf128_from_bytes(A, aad); aad += 16; aadlen -= 16; } else { memset(ctx->block, 0, 16); memcpy(ctx->block, aad, aadlen); - A = gf128_from_bytes(ctx->block); + gf128_from_bytes(A, ctx->block); aadlen = 0; } - ctx->X = gf128_add(ctx->X, A); - ctx->X = gf128_mul(ctx->X, ctx->H); + gf128_add(ctx->X, ctx->X, A); + gf128_mul(ctx->X, ctx->X, ctx->H); } } @@ -123,18 +126,18 @@ void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen) return; } else { memcpy(ctx->block + ctx->num, c, left); - C = gf128_from_bytes(ctx->block); - ctx->X = gf128_add(ctx->X, C); - ctx->X = gf128_mul(ctx->X, ctx->H); + gf128_from_bytes(C, ctx->block); + gf128_add(ctx->X, ctx->X, C); + gf128_mul(ctx->X, ctx->X, ctx->H); c += left; clen -= left; } } while (clen >= 16) { - C = gf128_from_bytes(c); - ctx->X = gf128_add(ctx->X, C); - ctx->X = gf128_mul(ctx->X, ctx->H); + gf128_from_bytes(C, c); + gf128_add(ctx->X, ctx->X, C); + gf128_mul(ctx->X, ctx->X, ctx->H); c += 16; clen -= 16; } @@ -152,17 +155,17 @@ void ghash_finish(GHASH_CTX *ctx, uint8_t out[16]) if (ctx->num) { memset(ctx->block + ctx->num, 0, 16 - ctx->num); - C = gf128_from_bytes(ctx->block); - ctx->X = gf128_add(ctx->X, C); - ctx->X = gf128_mul(ctx->X, ctx->H); + gf128_from_bytes(C, ctx->block); + gf128_add(ctx->X, ctx->X, C); + gf128_mul(ctx->X, ctx->X, ctx->H); } PUTU64(ctx->block, (uint64_t)ctx->aadlen << 3); PUTU64(ctx->block + 8, (uint64_t)ctx->clen << 3); - L = gf128_from_bytes(ctx->block); + gf128_from_bytes(L, ctx->block); - ctx->X = gf128_add(ctx->X, L); - ctx->H = gf128_mul(ctx->X, ctx->H); + gf128_add(ctx->X, ctx->X, L); + gf128_mul(ctx->H, ctx->X, ctx->H); gf128_to_bytes(ctx->H, out); gmssl_secure_clear(ctx, sizeof(*ctx)); diff --git a/tests/gf128test.c b/tests/gf128test.c index 47a99ead4..ddc298c0e 100644 --- a/tests/gf128test.c +++ b/tests/gf128test.c @@ -77,25 +77,17 @@ int test_gf128_mul_more(void) printf("test %zu\n", i); - a = gf128_from_hex(tests[i].a); - b = gf128_from_hex(tests[i].b); + gf128_from_hex(a, tests[i].a); + gf128_from_hex(b, tests[i].b); - printf("a0 = %llx, a1 = %llx\n", a.lo, a.hi); - printf("b0 = %llx, b1 = %llx\n", b.lo, b.hi); + gf128_mul(r, a, b); - r = gf128_mul(a, b); - - printf("r0 = %llx, r1 = %llx\n", r.lo, r.hi); - gf128_print_bits(a); - gf128_print_bits(b); - gf128_print_bits(r); + if (gf128_equ_hex(r, tests[i].r) != 1) { - gf128_to_bytes(r, buf); - format_bytes(stderr, 0, 0, "r" ,buf ,16); - if (gf128_equ_hex(r, tests[i].r) != 1) { + printf("error: %s\n", tests[i].label); error_print(); - //return -1; + return -1; } } @@ -103,39 +95,6 @@ int test_gf128_mul_more(void) return 1; } -int test_gf128_armv8(void) -{ - gf128_t a = { 1, 0 }; - gf128_t b = { 1, 0 }; - - a = gf128_from_hex("de300f9301a499a965f8bf677e99e80d"); - b = gf128_from_hex("14b267838ec9ef1bb7b5ce8c19e34bc6"); - - // pmull 是对低位做了乘法 - //gf128_print_bits(b); - - gf128_t c = gf128_mul(a, b); - - gf128_print_bits(c); - return 1; -} - - -int test_gf128_print(void) -{ - gf128_t a = { 0, 0x8000000000000000 }; // a = 1 + 0*x + ... + 0*x^127 - gf128_print(stderr, 0, 0, "1 + 0*x + ... + 0*x^127", a); - - // 这个函数打印的不对,因为真正的值是需要 reverse_bits 的,但是这里我们没有反转 - gf128_print_bits(a); - - // 看来这个比较奇怪了 - - - return 1; - -} - int test_gf128_from_hex(void) { char *tests[] = { @@ -149,7 +108,7 @@ int test_gf128_from_hex(void) int i; for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - a = gf128_from_hex(tests[i]); + gf128_from_hex(a, tests[i]); if (gf128_equ_hex(a, tests[i]) != 1) { error_print(); return -1; @@ -160,7 +119,7 @@ int test_gf128_from_hex(void) return 1; } -int test_gf128_mul2(void) +int test_gf128_mul_by_2(void) { char *tests[] = { "00000000000000000000000000000001", @@ -174,8 +133,8 @@ int test_gf128_mul2(void) int i; for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - a = gf128_from_hex(tests[i]); - a = gf128_mul2(a); + gf128_from_hex(a, tests[i]); + gf128_mul_by_2(a, a); if (gf128_equ_hex(a, results[i]) != 1) { error_print(); return -1; @@ -196,16 +155,16 @@ int test_gf128_mul(void) char *hex_mul_a_b = "7d87dda57a20b0c51d9743071ab14010"; gf128_t a, b, r; - a = gf128_from_hex(hex_a); - b = gf128_from_hex(hex_b); + gf128_from_hex(a, hex_a); + gf128_from_hex(b, hex_b); - r = gf128_add(a, b); + gf128_add(r, a, b); if (gf128_equ_hex(r, hex_add_a_b) != 1) { error_print(); return -1; } - r = gf128_mul(a, b); + gf128_mul(r, a, b); if (gf128_equ_hex(r, hex_mul_a_b) != 1) { error_print(); return -1; @@ -217,11 +176,9 @@ int test_gf128_mul(void) int main(void) { - if (test_gf128_armv8() != 1) goto err; + if (test_gf128_mul_by_2() != 1) goto err; if (test_gf128_mul_more() != 1) goto err; - if (test_gf128_print() != 1) goto err; if (test_gf128_from_hex() != 1) goto err; - if (test_gf128_mul2() != 1) goto err; if (test_gf128_mul() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0;