diff --git a/.gitignore b/.gitignore index 3a7513d12..e085dcb33 100644 --- a/.gitignore +++ b/.gitignore @@ -231,6 +231,7 @@ examples/verilog/fulladder/simprofile_dir/ examples/verilog/fulladder/simv.daidir/ examples/verilog/fulladder/ucli.key examples/verilog/fulladder/verdi_config_file +examples/crypto/gfmul/gfmul tests/functcov tests/functcov/* tests/functcov/*/* diff --git a/examples/crypto/gfmul/Makefile b/examples/crypto/gfmul/Makefile new file mode 100644 index 000000000..a501c3775 --- /dev/null +++ b/examples/crypto/gfmul/Makefile @@ -0,0 +1,16 @@ +# Makefile + +CC = gcc +CFLAGS = -O3 +LIBS = +SRCS = $(wildcard *.c) + +PROGS = $(patsubst %.c,%,$(SRCS)) + +all: $(PROGS) + +%: %.c + $(CC) $(CFLAGS) $(IFLAGS) -o $@ $< $(LIBS) + +clean: + rm -f $(PROGS) diff --git a/examples/crypto/gfmul/gfmul.c b/examples/crypto/gfmul/gfmul.c new file mode 100644 index 000000000..3c4f585f1 --- /dev/null +++ b/examples/crypto/gfmul/gfmul.c @@ -0,0 +1,72 @@ +// gfmul.c - Galois Field multiplication +// James Stine and David Harris 16 May 2024 + +#include + +/* return ab mod m(x) - long multiplication in GF(2^n) with polynomial m */ +int gfmul(int a, int b, int n, int m) { + int result = 0; + while (b) { + if (b & 1) result = result ^ a; /* if bit of b is set add a */ + a = a << 1; /* multiply a by x */ + if (a & 1 << n) + a = a ^ m; /* reduce/sub modulo AES m(x) = 100011011 */ + //printf("a = %x, b = %x, result = %x\n", a, b, result); + b = b >> 1; /* get next bit of b */ + } + return result; +} + +void inverses(void) { + int i, j, k, num; + + printf("\nTable of inverses in GF(2^8) with polynomial m(x) = 100011011\n"); + for (i=0; i<16; i++) { + for (j=0; j<16; j++) { + num = i*16+j; + if (num ==0) printf ("00 "); + else for (k=1; k<256; k++) { + if (gfmul(num, k, 8, 0b100011011) == 1) { + printf("%02x ", k); + break; + } + } + } + printf("\n"); + } +} + +void inverses3(void) { + int k, num; + + printf("\nTable of inverses in GF(2^8) with polynomial m(x) = 100011011\n"); + for (num=0; num<8; num++) { + if (num == 0) printf ("0 "); + else for (k=1; k<8; k++) { + if (gfmul(num, k, 3, 0b1011) == 1) { + printf("%d ", k); + break; + } + } + } + printf("\n"); +} + + +int main() { + int a = 0xC5; + int b = 0xA1; + + printf("The GF(2^8) result is %x\n", gfmul(a,b, 8, 0b100011011)); + printf("The GF(2^8) result is %x\n", gfmul(0xC1, 0x28, 8, 0b100011011)); + inverses(); + + // tabulate inverses for GF(2^3) + inverses3(); + // check worked examples + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b011, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b010, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b100, 3, 0b1011)); + printf("The GF(2^3) result is %d\n", gfmul(0b101,0b011, 3, 0b1011)); + +}