From 8d18377c0c95e61c623070af6b84967e38c38e9d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 17 Sep 2023 13:13:57 +0100 Subject: [PATCH] add implementation of poly1305 pure python by Hubert Kario, LGPLv2.1 licensed --- src/openpower/decoder/isa/poly1305.py | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/openpower/decoder/isa/poly1305.py diff --git a/src/openpower/decoder/isa/poly1305.py b/src/openpower/decoder/isa/poly1305.py new file mode 100644 index 00000000..83411597 --- /dev/null +++ b/src/openpower/decoder/isa/poly1305.py @@ -0,0 +1,48 @@ +# Copyright (c) 2015, Hubert Kario +# License: LGPLv2.1 +"""Implementation of Poly1305 authenticator for RFC 7539""" + +def divceil(a, b): return -(a // -b) + +class Poly1305(object): + + """Poly1305 authenticator""" + + P = 0x3fffffffffffffffffffffffffffffffb # 2^130-5 + + @staticmethod + def le_bytes_to_num(data): + """Convert a number from little endian byte format""" + ret = 0 + for i in range(len(data) - 1, -1, -1): + ret <<= 8 + ret += data[i] + return ret + + @staticmethod + def num_to_16_le_bytes(num): + """Convert number to 16 bytes in little endian format""" + ret = [0]*16 + for i, _ in enumerate(ret): + ret[i] = num & 0xff + num >>= 8 + return bytearray(ret) + + def __init__(self, key): + """Set the authenticator key""" + if len(key) != 32: + raise ValueError("Key must be 256 bit long") + self.acc = 0 + self.r = self.le_bytes_to_num(key[0:16]) + self.r &= 0x0ffffffc0ffffffc0ffffffc0fffffff + self.s = self.le_bytes_to_num(key[16:32]) + + def create_tag(self, data): + """Calculate authentication tag for data""" + for i in range(0, divceil(len(data), 16)): + n = self.le_bytes_to_num(data[i*16:(i+1)*16] + b'\x01') + self.acc += n + self.acc = (self.r * self.acc) % self.P + self.acc += self.s + return self.num_to_16_le_bytes(self.acc) + -- 2.30.2