def decode(buffer: bytes, **kwargs) -> object: """ Decodes a JWK JSON string into EdDSA parameters. Parameters: buffer (bytes/str): JWK JSON string. Returns: EdDSA: EdDSA object. """ from samson.public_key.eddsa import EdDSA from samson.protocols.dh25519 import DH25519 if issubclass(type(buffer), (bytes, bytearray)): buffer = buffer.decode() jwk = json.loads(buffer) curve = JWK_INVERSE_CURVE_LOOKUP[jwk['crv']] x = Bytes(url_b64_decode(jwk['x'].encode('utf-8')), 'little') if 'd' in jwk: d = Bytes(url_b64_decode(jwk['d'].encode('utf-8'))).int() else: d = 0 if jwk['crv'] in ['Ed25519', 'Ed448']: eddsa = EdDSA(curve=curve, d=d) eddsa.A = eddsa.decode_point(x) else: eddsa = DH25519(curve=curve, d=d, pub=x.int()) return eddsa
def auth(self, ciphertext: Bytes, ad: Bytes, tag_mask: Bytes) -> Bytes: y = 0 y = self.update(y, ad) y = self.update(y, ciphertext) y ^= (len(ad) << (3 + 64)) | (len(ciphertext) << 3) y = self.mul(y) y ^= tag_mask.int() return Bytes(int.to_bytes(y, 16, 'big'))
def _run_oaep(self, e, d, modulus, bits, message, seed, expected_ciphertext): rsa = RSA(bits) rsa.e = e rsa.d = d rsa.n = modulus oaep = OAEP(rsa.bits) padded_plain = oaep.pad(message, seed=seed) ciphertext = Bytes(rsa.encrypt(padded_plain)) self.assertEqual(ciphertext, expected_ciphertext) self.assertEqual(oaep.unpad(rsa.decrypt(ciphertext.int())), message)
def _xts(self, in_bytes: bytes, tweak: int, func: FunctionType, reverse_cts: bool = False) -> Bytes: in_bytes = Bytes.wrap(in_bytes) tweak_bytes = Bytes(tweak) X = self.sector_encryptor(tweak_bytes + b'\x00' * (16 - len(tweak_bytes)))[::-1].int() out_bytes = Bytes(b'') byte_chunks = in_bytes.chunk(16, allow_partials=True) for block in byte_chunks: if len(block) == 16: if X >> 128: X ^= 0x100000000000000000000000000000087 X = Bytes(X, 'little').zfill(16) out_bytes += func(block ^ X) ^ X X = X.int() X <<= 1 else: curr_X = X if X >> 128: X ^= 0x100000000000000000000000000000087 # Decryption needs to reverse the ordering of the X's. # Here I just throw out the last block, use the most recent X, # and then backpedal X. if reverse_cts: out_bytes = out_bytes[:-16] X = Bytes(X, 'little').zfill(16) last_chunk = func(byte_chunks[-2] ^ X) ^ X X = curr_X >> 1 else: out_bytes, last_chunk = out_bytes[:-16], out_bytes[-16:] stolen, left_over = last_chunk[len(block ):], last_chunk[:len(block)] padded_block = block + stolen X = Bytes(X, 'little').zfill(16) out_bytes += (func(padded_block ^ X) ^ X) + left_over return out_bytes
def decode_point(self, in_bytes: Bytes) -> TwistedEdwardsPoint: """ Decodes `Bytes` to a `TwistedEdwardsPoint`. Parameters: in_bytes (Bytes): `TwistedEdwardsPoint` encoded as `Bytes`. Returns: TwistedEdwardsPoint: Decoded point. """ y_bytes = Bytes([_ for _ in in_bytes], 'little') y_bytes[-1] &= 0x7F y = y_bytes.int() x = int(self.curve.recover_point_from_y(y).x) if (x & 1) != bit(in_bytes, self.curve.b - 1): x = self.curve.q - x return TwistedEdwardsPoint(x, y, self.curve)